4 void EntityFrame4_CL_ReadFrame(void)
6 int i, n, cnumber, referenceframenum, framenum, enumber, done, stopnumber, skip = false;
8 entityframe4_database_t *d;
9 if (!cl.entitydatabase4)
10 cl.entitydatabase4 = EntityFrame4_AllocDatabase(cls.levelmempool);
11 d = cl.entitydatabase4;
12 // read the number of the frame this refers to
13 referenceframenum = MSG_ReadLong(&cl_message);
14 // read the number of this frame
15 framenum = MSG_ReadLong(&cl_message);
16 CL_NewFrameReceived(framenum);
17 // read the start number
18 enumber = (unsigned short) MSG_ReadShort(&cl_message);
19 if (developer_networkentities.integer >= 10)
21 Con_Printf("recv svc_entities num:%i ref:%i database: ref:%i commits:", framenum, referenceframenum, d->referenceframenum);
22 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
23 if (d->commit[i].numentities)
24 Con_Printf(" %i", d->commit[i].framenum);
27 if (!EntityFrame4_AckFrame(d, referenceframenum, false))
29 Con_Print("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n");
32 d->currentcommit = NULL;
33 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
35 if (!d->commit[i].numentities)
37 d->currentcommit = d->commit + i;
38 d->currentcommit->framenum = framenum;
39 d->currentcommit->numentities = 0;
42 if (d->currentcommit == NULL)
44 Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, reading but not storing this update\n", framenum);
48 while (!done && !cl_message.badread)
50 // read the number of the modified entity
51 // (gaps will be copied unmodified)
52 n = (unsigned short)MSG_ReadShort(&cl_message);
55 // no more entities in this update, but we still need to copy the
56 // rest of the reference entities (final gap)
58 // read end of range number, then process normally
59 n = (unsigned short)MSG_ReadShort(&cl_message);
61 // high bit means it's a remove message
63 // if this is a live entity we may need to expand the array
64 if (cl.num_entities <= cnumber && !(n & 0x8000))
66 cl.num_entities = cnumber + 1;
67 if (cnumber >= cl.max_entities)
68 CL_ExpandEntities(cnumber);
70 // add one (the changed one) if not done
71 stopnumber = cnumber + !done;
72 // process entities in range from the last one to the changed one
73 for (;enumber < stopnumber;enumber++)
75 if (skip || enumber >= cl.num_entities)
77 if (enumber == cnumber && (n & 0x8000) == 0)
79 entity_state_t tempstate;
80 EntityState_ReadFields(&tempstate, EntityState_ReadExtendBits());
84 // slide the current into the previous slot
85 cl.entities[enumber].state_previous = cl.entities[enumber].state_current;
86 // copy a new current from reference database
87 cl.entities[enumber].state_current = *EntityFrame4_GetReferenceEntity(d, enumber);
88 s = &cl.entities[enumber].state_current;
89 // if this is the one to modify, read more data...
90 if (enumber == cnumber)
95 if (developer_networkentities.integer >= 2)
96 Con_Printf("entity %i: remove\n", enumber);
102 if (developer_networkentities.integer >= 2)
103 Con_Printf("entity %i: update\n", enumber);
104 s->active = ACTIVE_NETWORK;
105 EntityState_ReadFields(s, EntityState_ReadExtendBits());
108 else if (developer_networkentities.integer >= 4)
109 Con_Printf("entity %i: copy\n", enumber);
110 // set the cl.entities_active flag
111 cl.entities_active[enumber] = (s->active == ACTIVE_NETWORK);
112 // set the update time
113 s->time = cl.mtime[0];
114 // fix the number (it gets wiped occasionally by copying from defaultstate)
116 // check if we need to update the lerp stuff
117 if (s->active == ACTIVE_NETWORK)
118 CL_MoveLerpEntityStates(&cl.entities[enumber]);
119 // add this to the commit entry whether it is modified or not
120 if (d->currentcommit)
121 EntityFrame4_AddCommitEntity(d, &cl.entities[enumber].state_current);
122 // print extra messages if desired
123 if (developer_networkentities.integer >= 2 && cl.entities[enumber].state_current.active != cl.entities[enumber].state_previous.active)
125 if (cl.entities[enumber].state_current.active == ACTIVE_NETWORK)
126 Con_Printf("entity #%i has become active\n", enumber);
127 else if (cl.entities[enumber].state_previous.active)
128 Con_Printf("entity #%i has become inactive\n", enumber);
132 d->currentcommit = NULL;
134 EntityFrame4_ResetDatabase(d);