]> git.xonotic.org Git - xonotic/darkplaces.git/blob - cl_ents4.c
cl_main: Keep old CL_Disconnect for simplicity. Move guts to CL_DisconnectEx
[xonotic/darkplaces.git] / cl_ents4.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 void EntityFrame4_CL_ReadFrame(void)
5 {
6         int i, n, cnumber, referenceframenum, framenum, enumber, done, stopnumber, skip = false;
7         entity_state_t *s;
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)
20         {
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);
25                 Con_Print("\n");
26         }
27         if (!EntityFrame4_AckFrame(d, referenceframenum, false))
28         {
29                 Con_Print("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n");
30                 skip = true;
31         }
32         d->currentcommit = NULL;
33         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
34         {
35                 if (!d->commit[i].numentities)
36                 {
37                         d->currentcommit = d->commit + i;
38                         d->currentcommit->framenum = framenum;
39                         d->currentcommit->numentities = 0;
40                 }
41         }
42         if (d->currentcommit == NULL)
43         {
44                 Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, reading but not storing this update\n", framenum);
45                 skip = true;
46         }
47         done = false;
48         while (!done && !cl_message.badread)
49         {
50                 // read the number of the modified entity
51                 // (gaps will be copied unmodified)
52                 n = (unsigned short)MSG_ReadShort(&cl_message);
53                 if (n == 0x8000)
54                 {
55                         // no more entities in this update, but we still need to copy the
56                         // rest of the reference entities (final gap)
57                         done = true;
58                         // read end of range number, then process normally
59                         n = (unsigned short)MSG_ReadShort(&cl_message);
60                 }
61                 // high bit means it's a remove message
62                 cnumber = n & 0x7FFF;
63                 // if this is a live entity we may need to expand the array
64                 if (cl.num_entities <= cnumber && !(n & 0x8000))
65                 {
66                         cl.num_entities = cnumber + 1;
67                         if (cnumber >= cl.max_entities)
68                                 CL_ExpandEntities(cnumber);
69                 }
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++)
74                 {
75                         if (skip || enumber >= cl.num_entities)
76                         {
77                                 if (enumber == cnumber && (n & 0x8000) == 0)
78                                 {
79                                         entity_state_t tempstate;
80                                         EntityState_ReadFields(&tempstate, EntityState_ReadExtendBits());
81                                 }
82                                 continue;
83                         }
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)
91                         {
92                                 if (n & 0x8000)
93                                 {
94                                         // simply removed
95                                         if (developer_networkentities.integer >= 2)
96                                                 Con_Printf("entity %i: remove\n", enumber);
97                                         *s = defaultstate;
98                                 }
99                                 else
100                                 {
101                                         // read the changes
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());
106                                 }
107                         }
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)
115                         s->number = enumber;
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)
124                         {
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);
129                         }
130                 }
131         }
132         d->currentcommit = NULL;
133         if (skip)
134                 EntityFrame4_ResetDatabase(d);
135 }