/* ================ CG_AddFireEffect ================ */ static void CG_AddFireEffect( localEntity_t *le ) { refEntity_t *re; trace_t trace; re = &le->refEntity; if ( le->pos.trType == TR_STATIONARY ) { if ( le->leFlags & LEF_LESSOVERDRAW ) { // avoid too much overdraw if ( CG_NearbyDrawnLeCount( le, re->origin, le->leType, 52 + !!cg_lowDetailEffects.integer * 24 ) > 0 ) return; } // add to refresh list trap_R_AddRefEntityToScene( re ); return; } // calculate position BG_EvaluateTrajectory( &le->pos, cg.time, re->origin ); // check for water if ( trap_CM_PointContents( re->origin, 0 ) & CONTENTS_WATER ) { // do a trace to get water surface normals CG_Trace( &trace, re->oldorigin, NULL, NULL, re->origin, le->owner, MASK_WATER ); CG_FreeLocalEntity( le ); CG_MakeExplosion( trace.endpos, trace.plane.normal, cgs.media.ringFlashModel, cgs.media.vaporShader, 500, qfalse, qtrue ); return; } // do a trace sometimes if ( le->ti.trailTime++ > 5 ) { le->ti.trailTime = 0; CG_Trace( &trace, re->oldorigin, NULL, NULL, re->origin, le->owner, MASK_SHOT ); VectorCopy( trace.endpos, re->origin ); VectorCopy( trace.endpos, re->oldorigin ); // hit something if ( trace.fraction < 1.0 ) { // free le if another one is nearby, otherwise make it stationary if ( CG_CheckDistance( re->origin, le->leType, TR_STATIONARY, re->customShader, 200, 32 ) ) { CG_FreeLocalEntity( le ); return; } else { le->pos.trType = TR_STATIONARY; } } } if ( le->leFlags & LEF_LESSOVERDRAW ) { // avoid too much overdraw if ( CG_NearbyDrawnLeCount( le, re->origin, le->leType, 52 + !!cg_lowDetailEffects.integer * 24 ) > 0 ) return; } // add to refresh list trap_R_AddRefEntityToScene( re ); }
void CG_AddGore( localEntity_t *le ) { vec3_t newOrigin; trace_t trace; if ( le->pos.trType == TR_STATIONARY ) { // sink into the ground if near the removal time //int t; //float oldZ; CG_FreeLocalEntity( le ); // kill it return; } // calculate new position BG_EvaluateTrajectory( &le->pos, cg.time, newOrigin ); // trace a line from previous position to new position CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID ); if ( trace.fraction == 1.0 ) { // still in free fall VectorCopy( newOrigin, le->refEntity.origin ); if ( le->leFlags & LEF_TUMBLE ) { vec3_t angles; BG_EvaluateTrajectory( &le->angles, cg.time, angles ); AnglesToAxis( angles, le->refEntity.axis ); } trap_R_AddRefEntityToScene( &le->refEntity ); CG_SmallBloodTrail( le ); return; } // if it is in a nodrop zone, remove it // this keeps gibs from waiting at the bottom of pits of death // and floating levels if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) { CG_FreeLocalEntity( le ); return; } // leave a mark CG_GoreMark( le, &trace ); // do a juicy sound CG_SplatSound( le, &trace ); CG_JustSplat( le, &trace ); trap_R_AddRefEntityToScene( &le->refEntity ); }
/* ================ CG_AddExplosion ================ */ static void CG_AddExplosion( localEntity_t *ex ) { refEntity_t *ent; ent = &ex->refEntity; // add the entity // RF, don't add if shader is invalid if ( ent->customShader >= 0 ) { trap_R_AddRefEntityToScene( ent ); } // add the dlight if ( ex->light ) { float light; light = (float)( cg.time - ex->startTime ) / ( ex->endTime - ex->startTime ); if ( light < 0.5 ) { light = 1.0; } else { light = 1.0 - ( light - 0.5 ) * 2; } light = ex->light * light; trap_R_AddLightToScene( ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2], 0 ); } }
/* ======================================================================================================================================= CG_AddExplosion ======================================================================================================================================= */ static void CG_AddExplosion(localEntity_t *le) { refEntity_t *ent; ent = &le->refEntity; // add the entity trap_R_AddRefEntityToScene(ent); // add the dlight if (le->light) { float light; float radius; float intensity; light = (float)(cg.time - le->startTime) / (le->endTime - le->startTime); if (light < 0.5) { light = 1.0; } else { light = 1.0 - (light - 0.5) * 2; } if (cg_fadeExplosions.integer) { radius = le->light; intensity = light; } else { radius = le->light * light; intensity = 1; } trap_R_AddLightToScene(le->refEntity.origin, radius, intensity, le->lightColor[0], le->lightColor[1], le->lightColor[2], 0); } }
/* ================ CG_AddExplosion ================ */ static void CG_AddExplosion(localEntity_t * ex) { refEntity_t *ent; ent = &ex->refEntity; // add the entity trap_R_AddRefEntityToScene(ent); // add the light if(ex->light) { float light; light = (float)(cg.time - ex->startTime) / (ex->endTime - ex->startTime); if(light < 0.5) { light = 1.0; } else { light = 1.0 - (light - 0.5) * 2; } light = ex->light * light; trap_R_AddLightToScene(ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2]); } }
/* ================ CG_AddExplosion ================ */ static void CG_AddExplosion( localEntity_t *ex ) { refEntity_t *ent; float life; ent = &ex->refEntity; life = (float)( cg.time - ex->startTime ) / ( ex->endTime - ex->startTime ); // get colors ent->shaderRGBA[0] = 255 * ex->color[0] * ( 1.0 - life ); ent->shaderRGBA[1] = 255 * ex->color[1] * ( 1.0 - life ); ent->shaderRGBA[2] = 255 * ex->color[2] * ( 1.0 - life ); ent->shaderRGBA[3] = 255 * ex->color[3] * ( 1.0 - life ); // add the entity trap_R_AddRefEntityToScene(ent); // add the dlight if ( ex->light ) { float light; light = life; if ( light < 0.5 ) { light = 1.0; } else { light = 1.0 - ( light - 0.5 ) * 2; } light = ex->light * light; trap_R_AddLightToScene(ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2] ); } }
/* ========================== CG_GrappleTrail ========================== */ void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi ) { vec3_t origin; entityState_t *es; vec3_t forward, up; refEntity_t beam; es = &ent->currentState; BG_EvaluateTrajectory( &es->pos, cg.time, origin ); ent->trailTime = cg.time; memset( &beam, 0, sizeof( beam ) ); //FIXME adjust for muzzle position VectorCopy ( cg_entities[ ent->currentState.otherEntityNum ].lerpOrigin, beam.origin ); beam.origin[2] += 26; AngleVectors( cg_entities[ ent->currentState.otherEntityNum ].lerpAngles, forward, NULL, up ); VectorMA( beam.origin, -6, up, beam.origin ); VectorCopy( origin, beam.oldorigin ); if (Distance( beam.origin, beam.oldorigin ) < 64 ) return; // Don't draw if close beam.reType = RT_LIGHTNING; beam.customShader = cgs.media.lightningShader; AxisClear( beam.axis ); beam.shaderRGBA[0] = 0xff; beam.shaderRGBA[1] = 0xff; beam.shaderRGBA[2] = 0xff; beam.shaderRGBA[3] = 0xff; trap_R_AddRefEntityToScene( &beam ); }
static void CG_DrawScreenBlob(float redalpha, float greenalpha) { refEntity_t ent; float alphascale; float bluealpha = 0; // ragePro systems can't fade blends, so don't obscure the screen if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) { return; } memset( &ent, 0, sizeof( ent ) ); ent.reType = RT_SPRITE; ent.renderfx = RF_FIRST_PERSON; // Available input: // cg.damageValue: Range from 0 to 1, indicating the amount of damage. // cg.damageX and cg_damageY: Range from -1 to 1, indicating the location of the damage. VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin ); VectorMA( ent.origin, cg.damageX * -8, cg.refdef.viewaxis[1], ent.origin ); VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin ); // Here's the scoop: The closer we are to the center, the more transparent this blob is. alphascale = (2*fabs(cg.damageX)+fabs(cg.damageY))/3.0; redalpha *= alphascale; greenalpha *= alphascale; if (redalpha > greenalpha) { ent.data.sprite.radius = cg.damageValue * 15 * redalpha; } else { ent.data.sprite.radius = cg.damageShieldValue * 15 * greenalpha; } /* if (redalpha < 0.01) { // Just shield damage ent.customShader = cgs.media.shieldBlobShader; // Set all colors to the same as green, since the shader is green redalpha = bluealpha = greenalpha; } else*/ if (greenalpha < 0.01) { // Just pain damage ent.customShader = cgs.media.painBlobShader; // Set all colors to the same as red, since the shader is red greenalpha = bluealpha = redalpha; } else { // Both ent.customShader = cgs.media.painShieldBlobShader; } ent.shaderRGBA[0] = 0xff * redalpha; ent.shaderRGBA[1] = 0xff * greenalpha; ent.shaderRGBA[2] = 0xff * bluealpha; ent.shaderRGBA[3] = 0xff; trap_R_AddRefEntityToScene( &ent ); }
/* =================== CG_AddRefEntity =================== */ void CG_AddRefEntity( localEntity_t *le ) { if (le->endTime < cg.time) { CG_FreeLocalEntity( le ); return; } trap_R_AddRefEntityToScene( &le->refEntity ); }
/* =================== CG_AddScaleFade For rocket smokes that hang in place, fade out, and are removed if the view passes through them. There are often many of these, so it needs to be simple. =================== */ static void CG_AddScaleFade( localEntity_t *le ) { refEntity_t *re; float c; vec3_t delta; float len; re = &le->refEntity; // fade / grow time c = ( le->endTime - cg.time ) * le->lifeRate; re->shaderRGBA[3] = 0xff * c * le->color[3]; if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) { re->radius = le->radius * ( 1.0 - c ) + 8; } // if the view would be "inside" the sprite, kill the sprite // so it doesn't add too much overdraw VectorSubtract( re->origin, cg.refdef.vieworg, delta ); len = VectorLength( delta ); if ( len < le->radius ) { CG_FreeLocalEntity( le ); return; } trap_R_AddRefEntityToScene( re ); }
static void CG_AddFadeScaleModel( localEntity_t *le ) { refEntity_t *ent = &le->refEntity; float frac = ( cg.time - le->startTime )/((float)( le->endTime - le->startTime )); frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end ent->nonNormalizedAxes = qtrue; AxisCopy( axisDefault, ent->axis ); VectorScale( ent->axis[0], le->radius * frac, ent->axis[0] ); VectorScale( ent->axis[1], le->radius * frac, ent->axis[1] ); VectorScale( ent->axis[2], le->radius * 0.5f * frac, ent->axis[2] ); frac = 1.0f - frac; ent->shaderRGBA[0] = le->color[0] * frac; ent->shaderRGBA[1] = le->color[1] * frac; ent->shaderRGBA[2] = le->color[2] * frac; ent->shaderRGBA[3] = le->color[3] * frac; // add the entity trap_R_AddRefEntityToScene( ent ); }
/* ================ CG_AddSpriteExplosion ================ */ static void CG_AddSpriteExplosion( localEntity_t *le ) { refEntity_t re; float c; re = le->refEntity; c = ( le->endTime - cg.time ) / ( float ) ( le->endTime - le->startTime ); if ( c > 1 ) { c = 1.0; // can happen during connection problems } re.shaderRGBA[0] = 0xff; re.shaderRGBA[1] = 0xff; re.shaderRGBA[2] = 0xff; re.shaderRGBA[3] = 0xff * c * 0.33; re.reType = RT_SPRITE; re.radius = 42 * ( 1.0 - c ) + 30; trap_R_AddRefEntityToScene( &re ); // add the dlight if ( le->light ) { float light; light = (float)( cg.time - le->startTime ) / ( le->endTime - le->startTime ); if ( light < 0.5 ) { light = 1.0; } else { light = 1.0 - ( light - 0.5 ) * 2; } light = le->light * light; trap_R_AddLightToScene(re.origin, light, le->lightColor[0], le->lightColor[1], le->lightColor[2] ); } }
/* ================== CG_AddPuff ================== */ static void CG_AddPuff( localEntity_t *le ) { refEntity_t *re; float c; vec3_t delta; float len; re = &le->refEntity; // fade / grow time c = ( le->endTime - cg.time ) / (float)( le->endTime - le->startTime ); re->shaderRGBA[0] = le->color[0] * c; re->shaderRGBA[1] = le->color[1] * c; re->shaderRGBA[2] = le->color[2] * c; if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) { re->radius = le->radius * ( 1.0 - c ) + 8; } BG_EvaluateTrajectory( &le->pos, cg.time, re->origin ); // if the view would be "inside" the sprite, kill the sprite // so it doesn't add too much overdraw VectorSubtract( re->origin, cg.refdef.vieworg, delta ); len = VectorLength( delta ); if ( len < le->radius ) { CG_FreeLocalEntity( le ); return; } trap_R_AddRefEntityToScene( re ); }
static void CG_AddTestModel (void) { int i; // re-register the model, because the level may have changed cg.testModelEntity.hModel = trap_R_RegisterModel( cg.testModelName ); if (! cg.testModelEntity.hModel ) { CG_Printf ("Can't register model\n"); return; } // if testing a gun, set the origin reletive to the view origin if ( cg.testGun ) { VectorCopy( cg.refdef.vieworg, cg.testModelEntity.origin ); VectorCopy( cg.refdef.viewaxis[0], cg.testModelEntity.axis[0] ); VectorCopy( cg.refdef.viewaxis[1], cg.testModelEntity.axis[1] ); VectorCopy( cg.refdef.viewaxis[2], cg.testModelEntity.axis[2] ); // allow the position to be adjusted for (i=0 ; i<3 ; i++) { cg.testModelEntity.origin[i] += cg.refdef.viewaxis[0][i] * cg_gun_x.value; cg.testModelEntity.origin[i] += cg.refdef.viewaxis[1][i] * cg_gun_y.value; cg.testModelEntity.origin[i] += cg.refdef.viewaxis[2][i] * cg_gun_z.value; } } trap_R_AddRefEntityToScene( &cg.testModelEntity ); }
void CG_AddElectricity( localEntity_t *le ) { refEntity_t *re; float frac, alpha; re = &le->refEntity; frac = ( cg.time - le->startTime ) / ( float ) ( le->endTime - le->startTime ); if ( frac > 1 ) frac = 1.0; // can happen during connection problems else if (frac < 0) frac = 0.0; re->data.electricity.width = le->data.electricity.width + (le->data.electricity.dwidth*frac); // Calculate the current alpha. alpha = le->alpha + (le->dalpha * frac); re->shaderRGBA[0] = 0xff * alpha; re->shaderRGBA[1] = 0xff * alpha; re->shaderRGBA[2] = 0xff * alpha; re->shaderRGBA[3] = 0xff; re->reType = RT_ELECTRICITY; trap_R_AddRefEntityToScene( re ); }
/* =================== CG_AddLine2 For trek, for beams and the like. =================== */ void CG_AddLine2( localEntity_t *le ) { refEntity_t *re; float frac, alpha; vec3_t curRGB; re = &le->refEntity; frac = (cg.time - le->startTime) / ( float ) ( le->endTime - le->startTime ); if ( frac > 1 ) frac = 1.0; // can happen during connection problems else if (frac < 0) frac = 0.0; // Use the liferate to set the scale over time. re->data.line.width = le->data.line2.width + (le->data.line2.dwidth * frac); re->data.line.width2 = le->data.line2.width2 + (le->data.line2.dwidth2 * frac); if (re->data.line.width <= 0) { CG_FreeLocalEntity( le ); return; } // We will assume here that we want additive transparency effects. alpha = le->alpha + (le->dalpha * frac); VectorMA(le->data.line2.startRGB, frac, le->data.line2.dRGB, curRGB); re->shaderRGBA[0] = 0xff * alpha * curRGB[0]; re->shaderRGBA[1] = 0xff * alpha * curRGB[1]; re->shaderRGBA[2] = 0xff * alpha * curRGB[2]; re->shaderRGBA[3] = 0xff * alpha; // Yes, we could apply c to this too, but fading the color is better for lines. re->reType = RT_LINE2; trap_R_AddRefEntityToScene( re ); }
/* ================ CG_DrawSphere ================ */ void CG_DrawSphere( const vec3_t center, float radius, int customShader, const float *shaderRGBA ) { refEntity_t re; memset( &re, 0, sizeof( re ) ); re.reType = RT_MODEL; re.hModel = cgs.media.sphereModel; re.customShader = customShader; re.renderfx = RF_NOSHADOW; if ( shaderRGBA != NULL ) { int i; for ( i = 0; i < 4; ++i ) { re.shaderRGBA[ i ] = 255 * shaderRGBA[ i ]; } } VectorCopy( center, re.origin ); radius *= 0.01f; VectorSet( re.axis[ 0 ], radius, 0, 0 ); VectorSet( re.axis[ 1 ], 0, radius, 0 ); VectorSet( re.axis[ 2 ], 0, 0, radius ); re.nonNormalizedAxes = qtrue; trap_R_AddRefEntityToScene( &re ); }
/* ================ CG_DrawSphericalCone ================ */ void CG_DrawSphericalCone( const vec3_t tip, const vec3_t rotation, float radius, qboolean a240, int customShader, const float *shaderRGBA ) { refEntity_t re; memset( &re, 0, sizeof( re ) ); re.reType = RT_MODEL; re.hModel = a240 ? cgs.media.sphericalCone240Model : cgs.media.sphericalCone64Model; re.customShader = customShader; re.renderfx = RF_NOSHADOW; if ( shaderRGBA != NULL ) { int i; for ( i = 0; i < 4; ++i ) { re.shaderRGBA[ i ] = 255 * shaderRGBA[ i ]; } } VectorCopy( tip, re.origin ); radius *= 0.01f; AnglesToAxis( rotation, re.axis ); VectorScale( re.axis[ 0 ], radius, re.axis[ 0 ] ); VectorScale( re.axis[ 1 ], radius, re.axis[ 1 ] ); VectorScale( re.axis[ 2 ], radius, re.axis[ 2 ] ); re.nonNormalizedAxes = qtrue; trap_R_AddRefEntityToScene( &re ); }
/* ================= CG_AddFallScaleFade This is just an optimized CG_AddMoveScaleFade For blood mists that drift down, fade out, and are removed if the view passes through them. There are often 100+ of these, so it needs to be simple. ================= */ static void CG_AddFallScaleFade( localEntity_t *le ) { refEntity_t *re; float c; vec3_t delta; float len; re = &le->refEntity; // fade time c = ( le->endTime - cg.time ) * le->lifeRate; re->shaderRGBA[3] = 0xff * c * le->color[3]; re->origin[2] = le->pos.trBase[2] - ( 1.0 - c ) * le->pos.trDelta[2]; re->radius = le->radius * ( 1.0 - c ) + 16; // if the view would be "inside" the sprite, kill the sprite // so it doesn't add too much overdraw VectorSubtract( re->origin, cg.refdef.vieworg, delta ); len = VectorLength( delta ); if ( len < le->radius ) { CG_FreeLocalEntity( le ); return; } trap_R_AddRefEntityToScene( re ); }
void CG_AddGib( localEntity_t *le ) { const qhandle_t hShader = cgs.media.freezeShader; if ( le->refEntity.customShader == hShader ) { le->refEntity.customShader = 0; trap_R_AddRefEntityToScene( &le->refEntity ); le->refEntity.customShader = hShader; } }
/* ======================== CG_AddWeaponWithPowerups ======================== */ static void CG_AddWeaponWithPowerups( refEntity_t *gun, int powerups ) { // add powerup effects if ( powerups & ( 1 << PW_INVIS ) ) { gun->customShader = cgs.media.invisShader; trap_R_AddRefEntityToScene( gun ); } else { trap_R_AddRefEntityToScene( gun ); if ( powerups & ( 1 << PW_BATTLESUIT ) ) { gun->customShader = cgs.media.battleWeaponShader; trap_R_AddRefEntityToScene( gun ); } if ( powerups & ( 1 << PW_QUAD ) ) { gun->customShader = cgs.media.quadWeaponShader; trap_R_AddRefEntityToScene( gun ); } } }
/* =================== CG_AddLine for beams and the like. =================== */ void CG_AddLine( localEntity_t *le ) { refEntity_t *re; re = &le->refEntity; re->reType = RT_LINE; trap_R_AddRefEntityToScene( re ); }
/* =============== CG_ModelDoor =============== */ void CG_ModelDoor( centity_t *cent ) { static refEntity_t ent; // static for proper alignment in QVMs entityState_t *es; animation_t anim; lerpFrame_t *lf = ¢->lerpFrame; es = ¢->currentState; if ( !es->modelindex ) { return; } //create the render entity memset( &ent, 0, sizeof( ent ) ); VectorCopy( cent->lerpOrigin, ent.origin ); VectorCopy( cent->lerpOrigin, ent.oldorigin ); AnglesToAxis( cent->lerpAngles, ent.axis ); ent.renderfx = RF_NOSHADOW; //add the door model ent.skinNum = 0; ent.hModel = cgs.gameModels[ es->modelindex ]; //scale the door VectorScale( ent.axis[ 0 ], es->origin2[ 0 ], ent.axis[ 0 ] ); VectorScale( ent.axis[ 1 ], es->origin2[ 1 ], ent.axis[ 1 ] ); VectorScale( ent.axis[ 2 ], es->origin2[ 2 ], ent.axis[ 2 ] ); ent.nonNormalizedAxes = true; //setup animation anim.firstFrame = es->misc; anim.numFrames = es->weapon; anim.reversed = !es->legsAnim; anim.flipflop = false; anim.loopFrames = 0; anim.frameLerp = 1000 / es->torsoAnim; anim.initialLerp = 1000 / es->torsoAnim; //door changed state if ( es->legsAnim != cent->doorState ) { lf->animationTime = lf->frameTime + anim.initialLerp; cent->doorState = es->legsAnim; } lf->animation = &anim; //run animation CG_DoorAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp ); trap_R_AddRefEntityToScene( &ent ); }
static JSBool sys_addrefentitytoscene(JSContext *cx, unsigned argc, jsval *vp) { JSObject *obj; refEntity_t refent; memset(&refent, 0, sizeof(refEntity_t)); if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "o", &obj)) return JS_FALSE; JS_Object_ParseRefEntity(cx, obj, &refent); trap_R_AddRefEntityToScene(&refent); return JS_TRUE; }
/* ================ CG_AddSpriteExplosion ================ */ static void CG_AddSpriteExplosion( localEntity_t *le ) { refEntity_t re; float c; re = le->refEntity; c = ( le->endTime - cg.time ) / ( float ) ( le->endTime - le->startTime ); if ( c > 1 ) { c = 1.0; // can happen during connection problems } re.shaderRGBA[0] = 0xff; re.shaderRGBA[1] = 0xff; re.shaderRGBA[2] = 0xff; re.shaderRGBA[3] = 0xff * c * 0.33; re.reType = RT_SPRITE; re.radius = 42 * ( 1.0 - c ) + 30; // Ridah, move away from surface VectorMA( le->pos.trBase, ( 1.0 - c ), le->pos.trDelta, re.origin ); // done. // RF, don't add if shader is invalid if ( re.customShader >= 0 ) { trap_R_AddRefEntityToScene( &re ); } // add the dlight if ( le->light ) { float light; // Ridah, modified this so the light fades out rather than shrinking /* light = (float)( cg.time - le->startTime ) / ( le->endTime - le->startTime ); if ( light < 0.5 ) { light = 1.0; } else { light = 1.0 - ( light - 0.5 ) * 2; } light = le->light * light; trap_R_AddLightToScene(re.origin, light, le->lightColor[0], le->lightColor[1], le->lightColor[2], 0 ); */ light = (float)( cg.time - le->startTime ) / ( le->endTime - le->startTime ); if ( light < 0.5 ) { light = 1.0; } else { light = 1.0 - ( light - 0.5 ) * 2; } trap_R_AddLightToScene( re.origin, le->light, light * le->lightColor[0], light * le->lightColor[1], light * le->lightColor[2], 0 ); // done. } }
/* =============== UI_PlayerFloatSprite =============== */ static void UI_PlayerFloatSprite( playerInfo_t *pi, vec3_t origin, qhandle_t shader ) { refEntity_t ent; memset( &ent, 0, sizeof( ent ) ); VectorCopy( origin, ent.origin ); ent.origin[2] += 48; ent.reType = RT_SPRITE; ent.customShader = shader; ent.radius = 10; ent.renderfx = 0; trap_R_AddRefEntityToScene( &ent ); }
/* =============== CG_DamageBlendBlob =============== */ static void CG_DamageBlendBlob( void ) { int t; int maxTime; refEntity_t ent; if ( !cg.damageValue ) { return; } maxTime = DAMAGE_TIME; t = cg.time - cg.damageTime; if ( t <= 0 || t >= maxTime ) { return; } memset( &ent, 0, sizeof( ent ) ); ent.reType = RT_SPRITE; ent.renderfx = RF_FIRST_PERSON; VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin ); VectorMA( ent.origin, cg.damageX * -8, cg.refdef.viewaxis[1], ent.origin ); VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin ); ent.radius = cg.damageValue * 3 * ( 1.0 - ((float)t / maxTime) ); if (cg.snap->ps.damageType == 0) { //pure health ent.customShader = cgs.media.viewPainShader; ent.shaderRGBA[0] = 180 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[1] = 50 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[3] = 255; } else if (cg.snap->ps.damageType == 1) { //pure shields ent.customShader = cgs.media.viewPainShader_Shields; ent.shaderRGBA[0] = 50 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[1] = 180 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[3] = 255; } else { //shields and health ent.customShader = cgs.media.viewPainShader_ShieldsAndHealth; ent.shaderRGBA[0] = 180 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[1] = 180 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) ); ent.shaderRGBA[3] = 255; } trap_R_AddRefEntityToScene( &ent ); }
/* =================== CG_AddBezier For trek, for the imod and the...uh...imod. =================== */ void CG_AddBezier( localEntity_t *le ) { refEntity_t *re; float frac, alpha; float t = (cg.time - le->startTime)*0.001; // time elapsed since beginning of effect vec3_t vTempPos; re = &le->refEntity; frac = (cg.time - le->startTime) / ( float ) ( le->endTime - le->startTime ); if ( frac > 1 ) frac = 1.0; // can happen during connection problems else if (frac < 0) frac = 0.0; // Use the liferate to set the scale over time. re->data.bezier.width = le->data.line.width + (le->data.line.dwidth * frac); if (re->data.bezier.width <= 0) { CG_FreeLocalEntity( le ); return; } // We will assume here that we want additive transparency effects. alpha = le->alpha + (le->dalpha * frac); re->shaderRGBA[0] = 0xff * alpha; re->shaderRGBA[1] = 0xff * alpha; re->shaderRGBA[2] = 0xff * alpha; re->shaderRGBA[3] = 0xff; // Yes, we could apply c to this too, but fading the color is better for lines. re->reType = RT_BEZIER; // the refEntity only stores the two control points, so we need to update them here with //the control_velocity and control_acceleration, then store the results in refEntity. //use (cg.time - le->startTime) as a value for elapsed time t, plug it into the position formula: // // x = x0 + (v0 * t) + (0.5 * a * t * t) // //...where x is the position at time t, x0 is initial control point position, v0 is control point velocity, //and a is control point acceleration // // update control point 1 VectorMA(le->data.line.control1, t, le->data.line.control1_velocity, vTempPos); VectorMA(vTempPos, (0.5*t*t), le->data.line.control1_acceleration, re->data.bezier.control1); // update control point 2 VectorMA(le->data.line.control2, t, le->data.line.control2_velocity, vTempPos); VectorMA(vTempPos, (0.5*t*t), le->data.line.control2_acceleration, re->data.bezier.control2); trap_R_AddRefEntityToScene( re ); }
//TiM - Beam FX for the Neutrino Probe weapon void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire ) { trace_t tr; refEntity_t beam; vec3_t end; float scale; memset( &beam, 0, sizeof( beam ) ); if ( alt_fire ) scale = flrandom(7.0f, 12.0f); else scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) ); VectorMA( origin, PROBE_BEAM_LENGTH, dir, end ); CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID ); trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f ); VectorCopy( origin, beam.origin); VectorCopy( tr.endpos, beam.oldorigin ); beam.reType = RT_LINE; beam.customShader = cgs.media.probeBeam; beam.shaderRGBA[0] = 0xff; beam.shaderRGBA[1] = 0xff; beam.shaderRGBA[2] = 0xff; beam.shaderRGBA[3] = 0xff; AxisClear( beam.axis ); beam.data.line.width = scale*0.1; beam.data.line.width2 = scale; beam.data.line.stscale = 1.0; trap_R_AddRefEntityToScene( &beam ); if ( tr.fraction != 1.0f ) { float radius; if ( alt_fire ) radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3)); else radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3)); if ( !radius ) return; CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue ); trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f ); } }
/* ================== CG_GhostBuildable ================== */ void CG_GhostBuildable( buildable_t buildable ) { refEntity_t ent; playerState_t *ps; vec3_t angles, entity_origin; vec3_t mins, maxs; trace_t tr; float scale; ps = &cg.predictedPlayerState; memset( &ent, 0, sizeof( ent ) ); BG_FindBBoxForBuildable( buildable, mins, maxs ); BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, CG_Trace, entity_origin, angles, &tr ); CG_PositionAndOrientateBuildable( ps->viewangles, entity_origin, tr.plane.normal, ps->clientNum, mins, maxs, ent.axis, ent.origin ); //offset on the Z axis if required VectorMA( ent.origin, BG_FindZOffsetForBuildable( buildable ), tr.plane.normal, ent.origin ); VectorCopy( ent.origin, ent.lightingOrigin ); VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all ent.hModel = cg_buildables[ buildable ].models[ 0 ]; if( ps->stats[ STAT_BUILDABLE ] & SB_VALID_TOGGLEBIT ) ent.customShader = cgs.media.greenBuildShader; else ent.customShader = cgs.media.redBuildShader; //rescale the model scale = BG_FindModelScaleForBuildable( buildable ); if( scale != 1.0f ) { VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] ); VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] ); VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] ); ent.nonNormalizedAxes = qtrue; } else ent.nonNormalizedAxes = qfalse; // add to refresh list trap_R_AddRefEntityToScene( &ent ); }