qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType ) { if( !ent || !ent->model ) return false; if( entityType == ET_TEMPENTITY ) { // copy actual origin and angles back to let StudioModelRenderer // get actual value directly from curstate VectorCopy( ent->origin, ent->curstate.origin ); VectorCopy( ent->angles, ent->curstate.angles ); } if( CL_IsInMenu( ) && ( !cl.background || ent->player )) { // menu entities ignores client filter if( !R_AddEntity( ent, entityType )) return false; } else { // check for adding this entity if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name )) return false; // don't add himself on firstperson if( RP_LOCALCLIENT( ent ) && !cl.thirdperson && cls.key_dest != key_menu && cl.refdef.viewentity == ( cl.playernum + 1 )) { if( gl_allow_mirrors->integer && world.has_mirrors ) { if( !R_AddEntity( ent, entityType )) return false; } // otherwise just pass to player effects like flashlight, particles etc } else if( entityType == ET_BEAM ) { CL_AddCustomBeam( ent ); return true; } else if( !R_AddEntity( ent, entityType )) { return false; } } // set actual entity type ent->curstate.entityType = entityType; // apply effects if( ent->curstate.effects & EF_BRIGHTFIELD ) CL_EntityParticles( ent ); // add in muzzleflash effect if( ent->curstate.effects & EF_MUZZLEFLASH ) { dlight_t *dl; if( ent == &clgame.viewent ) ent->curstate.effects &= ~EF_MUZZLEFLASH; dl = CL_AllocElight( 0 ); VectorCopy( ent->attachment[0], dl->origin ); dl->die = cl.time + 0.05f; dl->color.r = 255; dl->color.g = 180; dl->color.b = 64; dl->radius = 100; } // add light effect if( ent->curstate.effects & EF_LIGHT ) { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->die = cl.time; // die at next frame dl->color.r = 100; dl->color.g = 100; dl->color.b = 100; dl->radius = 200; CL_RocketFlare( ent->origin ); } // add dimlight if( ent->curstate.effects & EF_DIMLIGHT ) { if( entityType == ET_PLAYER ) { CL_UpdateFlashlight( ent ); } else { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->die = cl.time; // die at next frame dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; dl->radius = Com_RandomLong( 200, 230 ); } } if( ent->curstate.effects & EF_BRIGHTLIGHT ) { dlight_t *dl = CL_AllocDlight( 0 ); VectorSet( dl->origin, ent->origin[0], ent->origin[1], ent->origin[2] + 16.0f ); dl->die = cl.time + 0.001f; // die at next frame dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; if( entityType == ET_PLAYER ) dl->radius = 430; else dl->radius = Com_RandomLong( 400, 430 ); } if( ent->model->type == mod_studio ) { if( ent->model->flags & STUDIO_ROTATE ) ent->angles[1] = anglemod( 100.0f * cl.time ); if( ent->model->flags & STUDIO_GIB ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 2 ); else if( ent->model->flags & STUDIO_ZOMGIB ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 4 ); else if( ent->model->flags & STUDIO_TRACER ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 3 ); else if( ent->model->flags & STUDIO_TRACER2 ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 5 ); else if( ent->model->flags & STUDIO_ROCKET ) { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; // HACKHACK: get radius from head entity if( ent->curstate.rendermode != kRenderNormal ) dl->radius = max( 0, ent->curstate.renderamt - 55 ); else dl->radius = 200; dl->die = cl.time + 0.01f; CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 0 ); } else if( ent->model->flags & STUDIO_GRENADE ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 1 ); else if( ent->model->flags & STUDIO_TRACER3 ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 6 ); } return true; }
void NQD_LinkEntities (void) { entity_t ent; centity_t *cent; entity_state_t *state; float f; struct model_s *model; int modelflags; vec3_t cur_origin; vec3_t old_origin; float autorotate; int i; int num; f = NQD_LerpPoint (); NQD_LerpPlayerinfo (f); autorotate = anglemod (100*cl.time); memset (&ent, 0, sizeof(ent)); for (num = 1; num < nq_num_entities; num++) { cent = &cl_entities[num]; state = ¢->current; if (cent->lastframe != cl_entframecount) continue; // not present in this frame MSG_UnpackOrigin (state->s_origin, cur_origin); if (state->effects & EF_BRIGHTFIELD) CL_EntityParticles (cur_origin); // spawn light flashes, even ones coming from invisible objects if (state->effects & EF_MUZZLEFLASH) { vec3_t angles, forward; cdlight_t *dl; dl = CL_AllocDlight (-num); MSG_UnpackAngles (state->s_angles, angles); AngleVectors (angles, forward, NULL, NULL); VectorMA (cur_origin, 18, forward, dl->origin); dl->origin[2] += 16; dl->radius = 200 + (rand()&31); dl->minlight = 32; dl->die = cl.time + 0.1; dl->type = lt_muzzleflash; } if (state->effects & EF_BRIGHTLIGHT) { if (state->modelindex != cl_playerindex || r_powerupglow.value) { vec3_t tmp; VectorCopy (cur_origin, tmp); tmp[2] += 16; V_AddDlight (state->number, tmp, 400 + (rand()&31), 0, lt_default); } } if (state->effects & EF_DIMLIGHT) if (state->modelindex != cl_playerindex || r_powerupglow.value) V_AddDlight (state->number, cur_origin, 200 + (rand()&31), 0, lt_default); // if set to invisible, skip if (!state->modelindex) continue; cent->current = *state; ent.model = model = cl.model_precache[state->modelindex]; if (!model) Host_Error ("CL_LinkPacketEntities: bad modelindex"); if (cl_r2g.value && cl_grenadeindex != -1) if (state->modelindex == cl_rocketindex) ent.model = cl.model_precache[cl_grenadeindex]; modelflags = R_ModelFlags (model); // rotate binary objects locally if (modelflags & MF_ROTATE) { ent.angles[0] = 0; ent.angles[1] = autorotate; ent.angles[2] = 0; } else { vec3_t old, cur; MSG_UnpackAngles (cent->current.s_angles, old); MSG_UnpackAngles (cent->previous.s_angles, cur); LerpAngles (old, cur, f, ent.angles); } if (num == nq_viewentity) { extern float nq_speed; float f; nq_speed = 0; for (i = 0; i < 3; i++) { f = (cent->current.s_origin[i] - cent->previous.s_origin[i]) * 0.125; nq_speed += f * f; } if (nq_speed) nq_speed = sqrt(nq_speed); nq_speed /= nq_mtime[0] - nq_mtime[1]; } // calculate origin for (i = 0; i < 3; i++) { if (abs(cent->current.s_origin[i] - cent->previous.s_origin[i]) > 128 * 8) { // teleport or something, don't lerp VectorCopy (cur_origin, ent.origin); if (num == nq_viewentity) nq_player_teleported = true; break; } ent.origin[i] = cent->previous.s_origin[i] * 0.125 + f * (cur_origin[i] - cent->previous.s_origin[i] * 0.125); } if (num == nq_viewentity) { VectorCopy (ent.origin, cent->trail_origin); // FIXME? continue; // player entity } if (cl_deadbodyfilter.value && state->modelindex == cl_playerindex && ( (i=state->frame)==49 || i==60 || i==69 || i==84 || i==93 || i==102) ) continue; if (cl_gibfilter.value && cl.modelinfos[state->modelindex] == mi_gib) continue; // set colormap if (state->colormap && state->colormap <= MAX_CLIENTS && state->modelindex == cl_playerindex ) ent.colormap = state->colormap; else ent.colormap = 0; // set skin ent.skinnum = state->skinnum; // set frame ent.frame = state->frame; // add automatic particle trails if ((modelflags & ~MF_ROTATE)) { if (false /*cl_entframecount == 1 || cent->lastframe != cl_entframecount-1*/) { // not in last message VectorCopy (ent.origin, old_origin); } else { VectorCopy (cent->trail_origin, old_origin); for (i=0 ; i<3 ; i++) if ( abs(old_origin[i] - ent.origin[i]) > 128) { // no trail if too far VectorCopy (ent.origin, old_origin); break; } } if (modelflags & MF_ROCKET) { if (r_rockettrail.value) { if (r_rockettrail.value == 2) CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin); else CL_RocketTrail (old_origin, ent.origin, cent->trail_origin); } else VectorCopy (ent.origin, cent->trail_origin); if (r_rocketlight.value) CL_NewDlight (state->number, ent.origin, 200, 0.1, lt_rocket); } else if (modelflags & MF_GRENADE && r_grenadetrail.value) CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin); else if (modelflags & MF_GIB) CL_BloodTrail (old_origin, ent.origin, cent->trail_origin); else if (modelflags & MF_ZOMGIB) CL_SlightBloodTrail (old_origin, ent.origin, cent->trail_origin); else if (modelflags & MF_TRACER) CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 52); else if (modelflags & MF_TRACER2) CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 230); else if (modelflags & MF_TRACER3) CL_VoorTrail (old_origin, ent.origin, cent->trail_origin); } cent->lastframe = cl_entframecount; V_AddEntity (&ent); } if (nq_viewentity == 0) Host_Error ("viewentity == 0"); VectorCopy (cl_entities[nq_viewentity].trail_origin, cl.simorg); }