]> git.xonotic.org Git - xonotic/darkplaces.git/blob - cl_ents_nq.c
zone: Use the generic linked list
[xonotic/darkplaces.git] / cl_ents_nq.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 void EntityFrameQuake_ReadEntity(int bits)
5 {
6         int num;
7         entity_t *ent;
8         entity_state_t s;
9
10         if (bits & U_MOREBITS)
11                 bits |= (MSG_ReadByte(&cl_message)<<8);
12         if ((bits & U_EXTEND1) && cls.protocol != PROTOCOL_NEHAHRAMOVIE)
13         {
14                 bits |= MSG_ReadByte(&cl_message) << 16;
15                 if (bits & U_EXTEND2)
16                         bits |= MSG_ReadByte(&cl_message) << 24;
17         }
18
19         if (bits & U_LONGENTITY)
20                 num = (unsigned short) MSG_ReadShort(&cl_message);
21         else
22                 num = MSG_ReadByte(&cl_message);
23
24         if (num >= MAX_EDICTS)
25                 Host_Error("EntityFrameQuake_ReadEntity: entity number (%i) >= MAX_EDICTS (%i)", num, MAX_EDICTS);
26         if (num < 1)
27                 Host_Error("EntityFrameQuake_ReadEntity: invalid entity number (%i)", num);
28
29         if (cl.num_entities <= num)
30         {
31                 cl.num_entities = num + 1;
32                 if (num >= cl.max_entities)
33                         CL_ExpandEntities(num);
34         }
35
36         ent = cl.entities + num;
37
38         // note: this inherits the 'active' state of the baseline chosen
39         // (state_baseline is always active, state_current may not be active if
40         // the entity was missing in the last frame)
41         if (bits & U_DELTA)
42                 s = ent->state_current;
43         else
44         {
45                 s = ent->state_baseline;
46                 s.active = ACTIVE_NETWORK;
47         }
48
49         cl.isquakeentity[num] = true;
50         if (cl.lastquakeentity < num)
51                 cl.lastquakeentity = num;
52         s.number = num;
53         s.time = cl.mtime[0];
54         s.flags = 0;
55         if (bits & U_MODEL)
56         {
57                 if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
58                                                         s.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
59                 else
60                                                         s.modelindex = (s.modelindex & 0xFF00) | MSG_ReadByte(&cl_message);
61         }
62         if (bits & U_FRAME)             s.frame = (s.frame & 0xFF00) | MSG_ReadByte(&cl_message);
63         if (bits & U_COLORMAP)  s.colormap = MSG_ReadByte(&cl_message);
64         if (bits & U_SKIN)              s.skin = MSG_ReadByte(&cl_message);
65         if (bits & U_EFFECTS)   s.effects = (s.effects & 0xFF00) | MSG_ReadByte(&cl_message);
66         if (bits & U_ORIGIN1)   s.origin[0] = MSG_ReadCoord(&cl_message, cls.protocol);
67         if (bits & U_ANGLE1)    s.angles[0] = MSG_ReadAngle(&cl_message, cls.protocol);
68         if (bits & U_ORIGIN2)   s.origin[1] = MSG_ReadCoord(&cl_message, cls.protocol);
69         if (bits & U_ANGLE2)    s.angles[1] = MSG_ReadAngle(&cl_message, cls.protocol);
70         if (bits & U_ORIGIN3)   s.origin[2] = MSG_ReadCoord(&cl_message, cls.protocol);
71         if (bits & U_ANGLE3)    s.angles[2] = MSG_ReadAngle(&cl_message, cls.protocol);
72         if (bits & U_STEP)              s.flags |= RENDER_STEP;
73         if (bits & U_ALPHA)             s.alpha = MSG_ReadByte(&cl_message);
74         if (bits & U_SCALE)             s.scale = MSG_ReadByte(&cl_message);
75         if (bits & U_EFFECTS2)  s.effects = (s.effects & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
76         if (bits & U_GLOWSIZE)  s.glowsize = MSG_ReadByte(&cl_message);
77         if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte(&cl_message);
78         if (bits & U_COLORMOD)  {int c = MSG_ReadByte(&cl_message);s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));}
79         if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL;
80         if (bits & U_FRAME2)    s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
81         if (bits & U_MODEL2)    s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
82         if (bits & U_VIEWMODEL) s.flags |= RENDER_VIEWMODEL;
83         if (bits & U_EXTERIORMODEL)     s.flags |= RENDER_EXTERIORMODEL;
84
85         // LadyHavoc: to allow playback of the Nehahra movie
86         if (cls.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1))
87         {
88                 // LadyHavoc: evil format
89                 int i = (int)MSG_ReadFloat(&cl_message);
90                 int j = (int)(MSG_ReadFloat(&cl_message) * 255.0f);
91                 if (i == 2)
92                 {
93                         i = (int)MSG_ReadFloat(&cl_message);
94                         if (i)
95                                 s.effects |= EF_FULLBRIGHT;
96                 }
97                 if (j < 0)
98                         s.alpha = 0;
99                 else if (j == 0 || j >= 255)
100                         s.alpha = 255;
101                 else
102                         s.alpha = j;
103         }
104
105         ent->state_previous = ent->state_current;
106         ent->state_current = s;
107         if (ent->state_current.active == ACTIVE_NETWORK)
108         {
109                 CL_MoveLerpEntityStates(ent);
110                 cl.entities_active[ent->state_current.number] = true;
111         }
112
113         if (cl_message.badread)
114                 Host_Error("EntityFrameQuake_ReadEntity: read error");
115 }
116
117 void EntityFrameQuake_ISeeDeadEntities(void)
118 {
119         int num, lastentity;
120         if (cl.lastquakeentity == 0)
121                 return;
122         lastentity = cl.lastquakeentity;
123         cl.lastquakeentity = 0;
124         for (num = 0;num <= lastentity;num++)
125         {
126                 if (cl.isquakeentity[num])
127                 {
128                         if (cl.entities_active[num] && cl.entities[num].state_current.time == cl.mtime[0])
129                         {
130                                 cl.isquakeentity[num] = true;
131                                 cl.lastquakeentity = num;
132                         }
133                         else
134                         {
135                                 cl.isquakeentity[num] = false;
136                                 cl.entities_active[num] = ACTIVE_NOT;
137                                 cl.entities[num].state_current = defaultstate;
138                                 cl.entities[num].state_current.number = num;
139                         }
140                 }
141         }
142 }