1 // generic CSQC model code
6 #define ALLPROPERTIES \
7 PROPERTY(1, ReadCoord, WriteCoord, origin_x) \
8 PROPERTY(1, ReadCoord, WriteCoord, origin_y) \
9 PROPERTY(1, ReadCoord, WriteCoord, origin_z) \
10 PROPERTY(2, ReadAngle, WriteAngle, angles_x) \
11 PROPERTY(2, ReadAngle, WriteAngle, angles_y) \
12 PROPERTY(2, ReadAngle, WriteAngle, angles_z) \
13 PROPERTY(4, ReadShort, WriteShort, modelindex) \
14 PROPERTY(8, ReadByte, WriteByte, frame) \
15 PROPERTY(16, ReadByte, WriteByte, skin) \
16 PROPERTY(32, ReadInt24_t, WriteInt24_t, effects) \
17 PROPERTY_SCALED(64, ReadByte, WriteByte, alpha, 255, 0, 255) \
18 PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_x, 32, 0, 255) \
19 PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_y, 32, 0, 255) \
20 PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_z, 32, 0, 255) \
21 PROPERTY(256, ReadChar, WriteChar, view_ofs_z) \
22 PROPERTY(512, ReadShort, WriteShort, colormap)
26 #define PROPERTY(flag,r,w,f) \
28 #define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f)
30 #undef PROPERTY_SCALED
33 float CSQCModel_Send(entity to, float sf)
35 WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL);
36 WriteShort(MSG_ENTITY, sf);
38 #define PROPERTY(flag,r,w,f) \
41 w(MSG_ENTITY, self.csqcmodel_##f); \
43 #define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f)
45 #undef PROPERTY_SCALED
51 void CSQCModel_CheckUpdate()
54 #define PROPERTY(flag,r,w,f) \
56 if(tmp != self.csqcmodel_##f) \
58 self.csqcmodel_##f = tmp; \
59 self.SendFlags |= flag; \
61 #define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \
62 tmp = bound(mi, s * self.f, ma); \
63 if(tmp != self.csqcmodel_##f) \
65 self.csqcmodel_##f = tmp; \
66 self.SendFlags |= flag; \
69 #undef PROPERTY_SCALED
73 void CSQCModel_LinkEntity()
75 Net_LinkEntity(self, TRUE, 0, CSQCModel_Send);
84 InterpolateOrigin_Do();
88 vector player_org, player_vel;
89 float player_sequence, player_pmflags;
94 self.origin = player_org;
95 self.velocity = player_vel;
96 pmoveframe = player_sequence+1; //+1 because the recieved frame has the move already done (server side)
97 self.pmove_flags = player_pmflags;
98 if (pmoveframe < clientcommandframe-128)
99 pmoveframe = clientcommandframe-128; // don't want to loop infinitely
102 void PredictTo(float endframe)
104 if(servercommandframe >= player_sequence+63)
106 player_sequence = servercommandframe+63; // freeze laggers
112 if (getstatf(STAT_HEALTH) <= 0)
114 pmoveframe = clientcommandframe;
115 getinputstate(pmoveframe-1);
119 while(pmoveframe < endframe)
121 if (!getinputstate(pmoveframe))
125 runstandardplayerphysics(self);
130 //add in anything that was applied after (for low packet rate protocols)
131 input_angles = view_angles;
135 float autocvar_chase_active;
136 float autocvar_chase_back;
137 void CSQCModel_SetCamera()
145 PredictTo(clientcommandframe);
148 org = csqcmodel_me.origin + csqcmodel_me.view_ofs;
149 ang = R_SetView3fv(VF_ANGLES);
151 // simulate missing engine features
152 if(autocvar_chase_active)
156 dist = -autocvar_chase_back - 8;
158 chase_dest = org + v_forward * dist;
159 traceline(org, chase_dest, MOVE_NOMONSTERS, csqcmodel_me);
160 org = trace_endpos + 8 * v_forward + 4 * trace_plane_normal;
163 R_SetView3fv(VF_ORIGIN, org);
164 R_SetView3fv(VF_ANGLES, ang);
168 void CSQCModel_Read()
173 if(self.entnum == player_localentnum)
176 InterpolateOrigin_Undo();
178 #define PROPERTY(flag,r,w,f) \
181 #define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \
185 #undef PROPERTY_SCALED
189 if(self.entnum == player_localentnum)
195 PredictTo(servercommandframe + 1);
196 player_pmflags = self.pmove_flags;
199 player_sequence = servercommandframe;
203 InterpolateOrigin_Note();
206 if(self.entnum <= maxclients)
207 self.renderflags = RF_EXTERNALMODEL;
208 self.drawmask = MASK_NORMAL;
209 self.predraw = CSQCModel_Draw;