+ s->colormod[0] = MSG_ReadByte(&cl_message);
+ s->colormod[1] = MSG_ReadByte(&cl_message);
+ s->colormod[2] = MSG_ReadByte(&cl_message);
+ }
+ if (bits & E5_GLOWMOD)
+ {
+ s->glowmod[0] = MSG_ReadByte(&cl_message);
+ s->glowmod[1] = MSG_ReadByte(&cl_message);
+ s->glowmod[2] = MSG_ReadByte(&cl_message);
+ }
+ if (bits & E5_COMPLEXANIMATION)
+ {
+ skeleton_t *skeleton;
+ const dp_model_t *model;
+ int modelindex;
+ int type;
+ int bonenum;
+ int numbones;
+ short pose7s[7];
+ type = MSG_ReadByte(&cl_message);
+ switch(type)
+ {
+ case 0:
+ s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[1].frame = 0;
+ s->framegroupblend[2].frame = 0;
+ s->framegroupblend[3].frame = 0;
+ s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[1].start = 0;
+ s->framegroupblend[2].start = 0;
+ s->framegroupblend[3].start = 0;
+ s->framegroupblend[0].lerp = 1;
+ s->framegroupblend[1].lerp = 0;
+ s->framegroupblend[2].lerp = 0;
+ s->framegroupblend[3].lerp = 0;
+ break;
+ case 1:
+ s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[2].frame = 0;
+ s->framegroupblend[3].frame = 0;
+ s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[2].start = 0;
+ s->framegroupblend[3].start = 0;
+ s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[2].lerp = 0;
+ s->framegroupblend[3].lerp = 0;
+ break;
+ case 2:
+ s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[3].frame = 0;
+ s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[2].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[3].start = 0;
+ s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[3].lerp = 0;
+ break;
+ case 3:
+ s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[3].frame = MSG_ReadShort(&cl_message);
+ s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[2].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[3].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+ s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ s->framegroupblend[3].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+ break;
+ case 4:
+ if (!cl.engineskeletonobjects)
+ cl.engineskeletonobjects = (skeleton_t *) Mem_Alloc(cls.levelmempool, sizeof(*cl.engineskeletonobjects) * MAX_EDICTS);
+ skeleton = &cl.engineskeletonobjects[number];
+ modelindex = MSG_ReadShort(&cl_message);
+ model = CL_GetModelByIndex(modelindex);
+ numbones = MSG_ReadByte(&cl_message);
+ if (model && numbones != model->num_bones)
+ Host_Error("E5_COMPLEXANIMATION: model has different number of bones than network packet describes\n");
+ if (!skeleton->relativetransforms || skeleton->model != model)
+ {
+ skeleton->model = model;
+ skeleton->relativetransforms = (matrix4x4_t *) Mem_Realloc(cls.levelmempool, skeleton->relativetransforms, sizeof(*skeleton->relativetransforms) * skeleton->model->num_bones);
+ for (bonenum = 0;bonenum < model->num_bones;bonenum++)
+ skeleton->relativetransforms[bonenum] = identitymatrix;
+ }
+ for (bonenum = 0;bonenum < numbones;bonenum++)
+ {
+ pose7s[0] = (short)MSG_ReadShort(&cl_message);
+ pose7s[1] = (short)MSG_ReadShort(&cl_message);
+ pose7s[2] = (short)MSG_ReadShort(&cl_message);
+ pose7s[3] = (short)MSG_ReadShort(&cl_message);
+ pose7s[4] = (short)MSG_ReadShort(&cl_message);
+ pose7s[5] = (short)MSG_ReadShort(&cl_message);
+ pose7s[6] = (short)MSG_ReadShort(&cl_message);
+ Matrix4x4_FromBonePose7s(skeleton->relativetransforms + bonenum, 1.0f / 64.0f, pose7s);
+ }
+ s->skeletonobject = *skeleton;
+ break;
+ default:
+ Host_Error("E5_COMPLEXANIMATION: Parse error - unknown type %i\n", type);
+ break;
+ }