void CL_RelinkEntities(void) { entity_t *ent; int i, j; float frac, f, d; vec3_t delta; float bobjrotate; vec3_t oldorg; dlight_t *dl; // determine partial update time frac = CL_LerpPoint(); cl_numvisedicts = 0; // interpolate player info for (i = 0; i < 3; i++) cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); if (cls.demoplayback) { // interpolate the angles for (j = 0; j < 3; j++) { d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; cl.viewangles[j] = cl.mviewangles[1][j] + frac*d; } } bobjrotate = anglemod(100 * cl.time); // start on the entity after the world for (i = 1, ent = cl_entities + 1; i < cl.num_entities; i++, ent++) { if (!ent->model) { // empty slot if (ent->forcelink) R_RemoveEfrags(ent); // just became empty continue; } // if the object wasn't included in the last packet, remove it if (ent->msgtime != cl.mtime[0]) { ent->model = NULL; //qmb :interpolation // [email protected]: model transform interpolation ent->frame_start_time = 0; ent->translate_start_time = 0; ent->rotate_start_time = 0; //qmb :end continue; } VectorCopy(ent->origin, oldorg); if (ent->forcelink) { // the entity was not updated in the last message // so move to the final spot VectorCopy(ent->msg_origins[0], ent->origin); VectorCopy(ent->msg_angles[0], ent->angles); } else { // if the delta is large, assume a teleport and don't lerp f = frac; for (j = 0; j < 3; j++) { delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; if (delta[j] > 100 || delta[j] < -100) f = 1; // assume a teleportation, not a motion if (f >= 1) { ent->frame_start_time = 0; ent->translate_start_time = 0; ent->rotate_start_time = 0; } } // interpolate the origin and angles for (j = 0; j < 3; j++) { ent->origin[j] = ent->msg_origins[1][j] + f * delta[j]; d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; ent->angles[j] = ent->msg_angles[1][j] + f*d; } } // rotate binary objects locally if (ent->model->flags & EF_ROTATE) { ent->angles[1] = bobjrotate; // MUFF - makes them bob as well as rotate ;) ent->origin[2] += ((sin(bobjrotate / 90 * M_PI) * 5) + 5); } if (ent->effects & EF_BRIGHTFIELD) R_EntityParticles(ent); if (ent->effects & EF_MUZZLEFLASH) { vec3_t fv, rv, uv; dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->origin[2] += 16; AngleVectors(ent->angles, fv, rv, uv); VectorMA(dl->origin, 18, fv, dl->origin); dl->radius = 200 + (rand()&31); dl->minlight = 32; dl->die = cl.time + 0.1; dl->colour[0] = 0.6f; dl->colour[1] = 0.4f; dl->colour[2] = 0.2f; //qmb :coloured lighting } if (ent->effects & EF_BRIGHTLIGHT) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->origin[2] += 16; dl->radius = 400 + (rand()&31); dl->die = cl.time + 0.001; } if (ent->effects & EF_DIMLIGHT) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; } if (ent->model->flags & EF_GIB) R_RocketTrail(oldorg, ent->origin, 2); else if (ent->model->flags & EF_ZOMGIB) R_RocketTrail(oldorg, ent->origin, 4); else if (ent->model->flags & EF_TRACER) R_RocketTrail(oldorg, ent->origin, 3); else if (ent->model->flags & EF_TRACER2) R_RocketTrail(oldorg, ent->origin, 5); else if (ent->model->flags & EF_ROCKET) { R_RocketTrail(oldorg, ent->origin, 0); dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200; dl->die = cl.time + 0.01; dl->colour[0] = 0.6f; dl->colour[1] = 0.4f; dl->colour[2] = 0.4f; //qmb :coloured lighting } else if (ent->model->flags & EF_GRENADE) R_RocketTrail(oldorg, ent->origin, 1); else if (ent->model->flags & EF_TRACER3) R_RocketTrail(oldorg, ent->origin, 6); ent->forcelink = false; if (i == cl.viewentity) continue; if (cl_numvisedicts < MAX_VISEDICTS) { cl_visedicts[cl_numvisedicts] = ent; cl_numvisedicts++; } } }
/* =============== CL_RelinkEntities =============== */ void CL_RelinkEntities(void) { entity_t *ent; int i, j; float frac, f, d; vec3_t delta; float bobjrotate; vec3_t oldorg; dlight_t *dl; // determine partial update time frac = CL_LerpPoint(); cl_numvisedicts = 0; // // interpolate player info // for (i = 0; i < 3; i++) cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); if (cls.demoplayback) { // interpolate the angles for (j = 0; j < 3; j++) { d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; cl.viewangles[j] = cl.mviewangles[1][j] + frac * d; } } bobjrotate = anglemod(100 * cl.time); // start on the entity after the world for (i = 1, ent = cl_entities + 1; i < cl.num_entities; i++, ent++) { if (!ent->model) { // empty slot if (ent->forcelink) R_RemoveEfrags(ent); // just became empty continue; } // if the object wasn't included in the last packet, remove it if (ent->msgtime != cl.mtime[0]) { ent->model = NULL; continue; } VectorCopy(ent->origin, oldorg); if (ent->forcelink) { // the entity was not updated in the last message // so move to the final spot VectorCopy(ent->msg_origins[0], ent->origin); VectorCopy(ent->msg_angles[0], ent->angles); } else { // if the delta is large, assume a teleport and don't lerp f = frac; for (j = 0; j < 3; j++) { delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; if (delta[j] > 100 || delta[j] < -100) f = 1; // assume a teleportation, not a motion } // interpolate the origin and angles for (j = 0; j < 3; j++) { ent->origin[j] = ent->msg_origins[1][j] + f * delta[j]; d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; ent->angles[j] = ent->msg_angles[1][j] + f * d; } } // rotate binary objects locally if (ent->model->flags & EF_ROTATE) ent->angles[1] = bobjrotate; /* * FIXME - Some of these entity effects may be mutually exclusive? * work out which bits can be done better (e.g. I've already done the * RED|BLUE bit a little better...) */ if (ent->effects & EF_BRIGHTFIELD) R_EntityParticles(ent); if (ent->effects & EF_MUZZLEFLASH) { vec3_t fv, rv, uv; dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->origin[2] += 16; AngleVectors(ent->angles, fv, rv, uv); VectorMA(dl->origin, 18, fv, dl->origin); dl->radius = 200 + (rand() & 31); dl->minlight = 32; dl->die = cl.time + 0.1; dl->color = dl_colors[DLIGHT_FLASH]; } if (ent->effects & EF_BRIGHTLIGHT) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->origin[2] += 16; dl->radius = 400 + (rand() & 31); dl->die = cl.time + 0.001; dl->color = dl_colors[DLIGHT_FLASH]; } if (ent->effects & EF_DIMLIGHT) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200 + (rand() & 31); dl->die = cl.time + 0.001; dl->color = dl_colors[DLIGHT_FLASH]; } if ((ent->effects & (EF_RED | EF_BLUE)) == (EF_RED | EF_BLUE)) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200 + (rand() & 31); dl->die = cl.time + 0.001; dl->color = dl_colors[DLIGHT_PURPLE]; } else if (ent->effects & EF_BLUE) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200 + (rand() & 31); dl->die = cl.time + 0.001; dl->color = dl_colors[DLIGHT_BLUE]; } else if (ent->effects & EF_RED) { dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200 + (rand() & 31); dl->die = cl.time + 0.001; dl->color = dl_colors[DLIGHT_RED]; } if (ent->model->flags & EF_GIB) R_RocketTrail(oldorg, ent->origin, 2); else if (ent->model->flags & EF_ZOMGIB) R_RocketTrail(oldorg, ent->origin, 4); else if (ent->model->flags & EF_TRACER) R_RocketTrail(oldorg, ent->origin, 3); else if (ent->model->flags & EF_TRACER2) R_RocketTrail(oldorg, ent->origin, 5); else if (ent->model->flags & EF_ROCKET) { R_RocketTrail(oldorg, ent->origin, 0); dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200; dl->die = cl.time + 0.01; } else if (ent->model->flags & EF_GRENADE) R_RocketTrail(oldorg, ent->origin, 1); else if (ent->model->flags & EF_TRACER3) R_RocketTrail(oldorg, ent->origin, 6); ent->forcelink = false; if (i == cl.viewentity && !chase_active.value) continue; if (cl_numvisedicts < MAX_VISEDICTS) { cl_visedicts[cl_numvisedicts] = ent; cl_numvisedicts++; } } }