diff options
author | Tim Angus <tim@ngus.net> | 2005-12-10 03:23:37 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2005-12-10 03:23:37 +0000 |
commit | bf23ecf17f432cf8e47302ef7464612c17be9bbe (patch) | |
tree | 6e3d28ecaa038199d6ba63830e81f05270b199c3 /mod/src/cgame/cg_buildable.c | |
parent | 22f322884cf7715c01500ef0b4579b87b1cb1973 (diff) |
* Move the game source from mod/src/ to src/
Diffstat (limited to 'mod/src/cgame/cg_buildable.c')
-rw-r--r-- | mod/src/cgame/cg_buildable.c | 1051 |
1 files changed, 0 insertions, 1051 deletions
diff --git a/mod/src/cgame/cg_buildable.c b/mod/src/cgame/cg_buildable.c deleted file mode 100644 index 348bb433..00000000 --- a/mod/src/cgame/cg_buildable.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * Portions Copyright (C) 2000-2001 Tim Angus - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the OSML - Open Source Modification License v1.0 as - * described in the file COPYING which is distributed with this source - * code. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "cg_local.h" - -char *cg_buildableSoundNames[ MAX_BUILDABLE_ANIMATIONS ] = -{ - "construct1.wav", - "construct2.wav", - "idle1.wav", - "idle2.wav", - "idle3.wav", - "attack1.wav", - "attack2.wav", - "spawn1.wav", - "spawn2.wav", - "pain1.wav", - "pain2.wav", - "destroy1.wav", - "destroy2.wav", - "destroyed.wav" -}; - -static sfxHandle_t defaultAlienSounds[ MAX_BUILDABLE_ANIMATIONS ]; -static sfxHandle_t defaultHumanSounds[ MAX_BUILDABLE_ANIMATIONS ]; - -/* -=================== -CG_AlienBuildableExplosion - -Generated a bunch of gibs launching out from a location -=================== -*/ -void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir ) -{ - particleSystem_t *ps; - - trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.alienBuildableExplosion ); - - //particle system - ps = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDestroyedPS ); - - if( CG_IsParticleSystemValid( &ps ) ) - { - CG_SetAttachmentPoint( &ps->attachment, origin ); - CG_SetParticleSystemNormal( ps, dir ); - CG_AttachToPoint( &ps->attachment ); - } -} - -/* -================= -CG_HumanBuildableExplosion - -Called for human buildables as they are destroyed -================= -*/ -void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir ) -{ - particleSystem_t *ps; - - trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.humanBuildableExplosion ); - - //particle system - ps = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDestroyedPS ); - - if( CG_IsParticleSystemValid( &ps ) ) - { - CG_SetAttachmentPoint( &ps->attachment, origin ); - CG_SetParticleSystemNormal( ps, dir ); - CG_AttachToPoint( &ps->attachment ); - } -} - - -#define CREEP_SIZE 64.0f - -/* -================== -CG_Creep -================== -*/ -static void CG_Creep( centity_t *cent ) -{ - int msec; - float size, frac; - trace_t tr; - vec3_t temp, origin; - int scaleUpTime = BG_FindBuildTimeForBuildable( cent->currentState.modelindex ); - int time; - - time = cent->currentState.time; - - //should the creep be growing or receding? - if( time >= 0 ) - { - msec = cg.time - time; - if( msec >= 0 && msec < scaleUpTime ) - frac = (float)msec / scaleUpTime; - else - frac = 1.0f; - } - else if( time < 0 ) - { - msec = cg.time + time; - if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME ) - frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME ); - else - frac = 0.0f; - } - - VectorCopy( cent->currentState.origin2, temp ); - VectorScale( temp, -4096, temp ); - VectorAdd( temp, cent->lerpOrigin, temp ); - - CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_SOLID ); - - VectorCopy( tr.endpos, origin ); - - size = CREEP_SIZE * frac; - - if( size > 0.0f ) - CG_ImpactMark( cgs.media.creepShader, origin, cent->currentState.origin2, - 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue ); -} - -/* -====================== -CG_ParseBuildableAnimationFile - -Read a configuration file containing animation counts and rates -models/buildables/hivemind/animation.cfg, etc -====================== -*/ -static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_t buildable ) -{ - char *text_p; - int len; - int i; - char *token; - float fps; - char text[ 20000 ]; - fileHandle_t f; - animation_t *animations; - - animations = cg_buildables[ buildable ].animations; - - // load the file - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if( len <= 0 ) - return qfalse; - - if( len >= sizeof( text ) - 1 ) - { - CG_Printf( "File %s too long\n", filename ); - return qfalse; - } - - trap_FS_Read( text, len, f ); - text[ len ] = 0; - trap_FS_FCloseFile( f ); - - // parse the text - text_p = text; - - // read information for each frame - for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) - { - - token = COM_Parse( &text_p ); - if( !*token ) - break; - - animations[ i ].firstFrame = atoi( token ); - - token = COM_Parse( &text_p ); - if( !*token ) - break; - - animations[ i ].numFrames = atoi( token ); - animations[ i ].reversed = qfalse; - animations[ i ].flipflop = qfalse; - - // if numFrames is negative the animation is reversed - if( animations[ i ].numFrames < 0 ) - { - animations[ i ].numFrames = -animations[ i ].numFrames; - animations[ i ].reversed = qtrue; - } - - token = COM_Parse( &text_p ); - if ( !*token ) - break; - - animations[i].loopFrames = atoi( token ); - - token = COM_Parse( &text_p ); - if( !*token ) - break; - - fps = atof( token ); - if( fps == 0 ) - fps = 1; - - animations[ i ].frameLerp = 1000 / fps; - animations[ i ].initialLerp = 1000 / fps; - } - - if( i != MAX_BUILDABLE_ANIMATIONS ) - { - CG_Printf( "Error parsing animation file: %s\n", filename ); - return qfalse; - } - - return qtrue; -} - -/* -====================== -CG_ParseBuildableSoundFile - -Read a configuration file containing sound properties -sound/buildables/hivemind/sound.cfg, etc -====================== -*/ -static qboolean CG_ParseBuildableSoundFile( const char *filename, buildable_t buildable ) -{ - char *text_p; - int len; - int i; - char *token; - char text[ 20000 ]; - fileHandle_t f; - sound_t *sounds; - - sounds = cg_buildables[ buildable ].sounds; - - // load the file - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( len <= 0 ) - return qfalse; - - if ( len >= sizeof( text ) - 1 ) - { - CG_Printf( "File %s too long\n", filename ); - return qfalse; - } - - trap_FS_Read( text, len, f ); - text[len] = 0; - trap_FS_FCloseFile( f ); - - // parse the text - text_p = text; - - // read information for each frame - for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) - { - - token = COM_Parse( &text_p ); - if ( !*token ) - break; - - sounds[ i ].enabled = atoi( token ); - - token = COM_Parse( &text_p ); - if ( !*token ) - break; - - sounds[ i ].looped = atoi( token ); - - } - - if( i != MAX_BUILDABLE_ANIMATIONS ) - { - CG_Printf( "Error parsing sound file: %s\n", filename ); - return qfalse; - } - - return qtrue; -} -/* -=============== -CG_InitBuildables - -Initialises the animation db -=============== -*/ -void CG_InitBuildables( void ) -{ - char filename[ MAX_QPATH ]; - char soundfile[ MAX_QPATH ]; - char *buildableName; - char *modelFile; - int i; - int j; - fileHandle_t f; - - memset( cg_buildables, 0, sizeof( cg_buildables ) ); - - //default sounds - for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ ) - { - strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] ); - - Com_sprintf( filename, sizeof( filename ), "sound/buildables/alien/%s", soundfile ); - defaultAlienSounds[ j ] = trap_S_RegisterSound( filename, qfalse ); - - Com_sprintf( filename, sizeof( filename ), "sound/buildables/human/%s", soundfile ); - defaultHumanSounds[ j ] = trap_S_RegisterSound( filename, qfalse ); - } - - cg.buildablesFraction = 0.0f; - - for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ ) - { - buildableName = BG_FindNameForBuildable( i ); - - //animation.cfg - Com_sprintf( filename, sizeof( filename ), "models/buildables/%s/animation.cfg", buildableName ); - if ( !CG_ParseBuildableAnimationFile( filename, i ) ) - Com_Printf( S_COLOR_YELLOW "WARNING: failed to load animation file %s\n", filename ); - - //sound.cfg - Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/sound.cfg", buildableName ); - if ( !CG_ParseBuildableSoundFile( filename, i ) ) - Com_Printf( S_COLOR_YELLOW "WARNING: failed to load sound file %s\n", filename ); - - //models - for( j = 0; j <= 3; j++ ) - { - if( ( modelFile = BG_FindModelsForBuildable( i, j ) ) ) - cg_buildables[ i ].models[ j ] = trap_R_RegisterModel( modelFile ); - } - - //sounds - for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ ) - { - strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] ); - Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/%s", buildableName, soundfile ); - - if( cg_buildables[ i ].sounds[ j ].enabled ) - { - if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 ) - { - //file exists so close it - trap_FS_FCloseFile( f ); - - cg_buildables[ i ].sounds[ j ].sound = trap_S_RegisterSound( filename, qfalse ); - } - else - { - //file doesn't exist - use default - if( BG_FindTeamForBuildable( i ) == BIT_ALIENS ) - cg_buildables[ i ].sounds[ j ].sound = defaultAlienSounds[ j ]; - else - cg_buildables[ i ].sounds[ j ].sound = defaultHumanSounds[ j ]; - } - } - } - - cg.buildablesFraction = (float)i / (float)( BA_NUM_BUILDABLES - 1 ); - trap_UpdateScreen( ); - } - - cgs.media.teslaZapTS = CG_RegisterTrailSystem( "models/buildables/tesla/zap" ); -} - -/* -=============== -CG_SetBuildableLerpFrameAnimation - -may include ANIM_TOGGLEBIT -=============== -*/ -static void CG_SetBuildableLerpFrameAnimation( buildable_t buildable, lerpFrame_t *lf, int newAnimation ) -{ - animation_t *anim; - - lf->animationNumber = newAnimation; - - if( newAnimation < 0 || newAnimation >= MAX_BUILDABLE_ANIMATIONS ) - CG_Error( "Bad animation number: %i", newAnimation ); - - anim = &cg_buildables[ buildable ].animations[ newAnimation ]; - - //this item has just spawned so lf->frameTime will be zero - if( !lf->animation ) - lf->frameTime = cg.time + 1000; //1 sec delay before starting the spawn anim - - lf->animation = anim; - lf->animationTime = lf->frameTime + anim->initialLerp; - - if( cg_debugAnim.integer ) - CG_Printf( "Anim: %i\n", newAnimation ); -} - -/* -=============== -CG_RunBuildableLerpFrame - -Sets cg.snap, cg.oldFrame, and cg.backlerp -cg.time should be between oldFrameTime and frameTime after exit -=============== -*/ -static void CG_RunBuildableLerpFrame( centity_t *cent ) -{ - int f, numFrames; - buildable_t buildable = cent->currentState.modelindex; - lerpFrame_t *lf = ¢->lerpFrame; - animation_t *anim; - buildableAnimNumber_t newAnimation = cent->buildableAnim & ~( ANIM_TOGGLEBIT|ANIM_FORCEBIT ); - - // debugging tool to get no animations - if( cg_animSpeed.integer == 0 ) - { - lf->oldFrame = lf->frame = lf->backlerp = 0; - return; - } - - // see if the animation sequence is switching - if( newAnimation != lf->animationNumber || !lf->animation ) - { - if( cg_debugRandom.integer ) - CG_Printf( "newAnimation: %d lf->animationNumber: %d lf->animation: %d\n", - newAnimation, lf->animationNumber, lf->animation ); - - CG_SetBuildableLerpFrameAnimation( buildable, lf, newAnimation ); - - if( !cg_buildables[ buildable ].sounds[ newAnimation ].looped && - cg_buildables[ buildable ].sounds[ newAnimation ].enabled ) - { - if( cg_debugRandom.integer ) - CG_Printf( "Sound for animation %d for a %s\n", - newAnimation, BG_FindHumanNameForBuildable( buildable ) ); - - trap_S_StartSound( cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, - cg_buildables[ buildable ].sounds[ newAnimation ].sound ); - } - } - - if( cg_buildables[ buildable ].sounds[ lf->animationNumber ].looped && - cg_buildables[ buildable ].sounds[ lf->animationNumber ].enabled ) - trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, - cg_buildables[ buildable ].sounds[ lf->animationNumber ].sound ); - - // if we have passed the current frame, move it to - // oldFrame and calculate a new frame - if( cg.time >= lf->frameTime ) - { - lf->oldFrame = lf->frame; - lf->oldFrameTime = lf->frameTime; - - // get the next frame based on the animation - anim = lf->animation; - if( !anim->frameLerp ) - return; // shouldn't happen - - if ( cg.time < lf->animationTime ) - lf->frameTime = lf->animationTime; // initial lerp - else - lf->frameTime = lf->oldFrameTime + anim->frameLerp; - - f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; - numFrames = anim->numFrames; - if(anim->flipflop) - numFrames *= 2; - - if( f >= numFrames ) - { - f -= numFrames; - if( anim->loopFrames ) - { - f %= anim->loopFrames; - f += anim->numFrames - anim->loopFrames; - } - else - { - f = numFrames - 1; - // the animation is stuck at the end, so it - // can immediately transition to another sequence - lf->frameTime = cg.time; - cent->buildableAnim = cent->currentState.torsoAnim; - } - } - - if( anim->reversed ) - lf->frame = anim->firstFrame + anim->numFrames - 1 - f; - else if( anim->flipflop && f >= anim->numFrames ) - lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames ); - else - lf->frame = anim->firstFrame + f; - - if( cg.time > lf->frameTime ) - { - lf->frameTime = cg.time; - if( cg_debugAnim.integer ) - CG_Printf( "Clamp lf->frameTime\n"); - } - } - - if( lf->frameTime > cg.time + 200 ) - lf->frameTime = cg.time; - - if( lf->oldFrameTime > cg.time ) - lf->oldFrameTime = cg.time; - - // calculate current lerp value - if( lf->frameTime == lf->oldFrameTime ) - lf->backlerp = 0; - else - lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); -} - -/* -=============== -CG_BuildableAnimation -=============== -*/ -static void CG_BuildableAnimation( centity_t *cent, int *old, int *now, float *backLerp ) -{ - entityState_t *es = ¢->currentState; - - //if no animation is set default to idle anim - if( cent->buildableAnim == BANIM_NONE ) - cent->buildableAnim = es->torsoAnim; - - //display the first frame of the construction anim if not yet spawned - if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) - { - animation_t *anim = &cg_buildables[ es->modelindex ].animations[ BANIM_CONSTRUCT1 ]; - - //so that when animation starts for real it has sensible numbers - cent->lerpFrame.oldFrameTime = - cent->lerpFrame.frameTime = - cent->lerpFrame.animationTime = - cg.time; - - *old = cent->lerpFrame.oldFrame = anim->firstFrame; - *now = cent->lerpFrame.frame = anim->firstFrame; - *backLerp = cent->lerpFrame.backlerp = 0.0f; - - //ensure that an animation is triggered once the buildable has spawned - cent->oldBuildableAnim = BANIM_NONE; - } - else - { - if( ( cent->oldBuildableAnim ^ es->legsAnim ) & ANIM_TOGGLEBIT ) - { - if( cg_debugAnim.integer ) - CG_Printf( "%d->%d l:%d t:%d %s(%d)\n", - cent->oldBuildableAnim, cent->buildableAnim, - es->legsAnim, es->torsoAnim, - BG_FindHumanNameForBuildable( es->modelindex ), es->number ); - - if( cent->buildableAnim == es->torsoAnim || es->legsAnim & ANIM_FORCEBIT ) - cent->buildableAnim = cent->oldBuildableAnim = es->legsAnim; - else - cent->buildableAnim = cent->oldBuildableAnim = es->torsoAnim; - } - - CG_RunBuildableLerpFrame( cent ); - - *old = cent->lerpFrame.oldFrame; - *now = cent->lerpFrame.frame; - *backLerp = cent->lerpFrame.backlerp; - } -} - -#define TRACE_DEPTH 64.0f - -/* -=============== -CG_PositionAndOrientateBuildable -=============== -*/ -static void CG_PositionAndOrientateBuildable( const vec3_t angles, const vec3_t inOrigin, - const vec3_t normal, const int skipNumber, - const vec3_t mins, const vec3_t maxs, - vec3_t outAxis[ 3 ], vec3_t outOrigin ) -{ - vec3_t forward, start, end; - trace_t tr; - - AngleVectors( angles, forward, NULL, NULL ); - VectorCopy( normal, outAxis[ 2 ] ); - ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] ); - - if( !VectorNormalize( outAxis[ 0 ] ) ) - { - AngleVectors( angles, NULL, NULL, forward ); - ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] ); - VectorNormalize( outAxis[ 0 ] ); - } - - CrossProduct( outAxis[ 0 ], outAxis[ 2 ], outAxis[ 1 ] ); - outAxis[ 1 ][ 0 ] = -outAxis[ 1 ][ 0 ]; - outAxis[ 1 ][ 1 ] = -outAxis[ 1 ][ 1 ]; - outAxis[ 1 ][ 2 ] = -outAxis[ 1 ][ 2 ]; - - VectorMA( inOrigin, -TRACE_DEPTH, normal, end ); - VectorMA( inOrigin, 1.0f, normal, start ); - CG_CapTrace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID ); - - if( tr.fraction == 1.0f ) - { - //erm we missed completely - try again with a box trace - CG_Trace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID ); - } - - VectorMA( inOrigin, tr.fraction * -TRACE_DEPTH, normal, outOrigin ); -} - -/* -================== -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 ); -} - -/* -================== -CG_BuildableParticleEffects -================== -*/ -static void CG_BuildableParticleEffects( centity_t *cent ) -{ - entityState_t *es = ¢->currentState; - buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex ); - int health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - float healthFrac = (float)health / B_HEALTH_SCALE; - - if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) - return; - - if( team == BIT_HUMANS ) - { - if( healthFrac < 0.33f && !CG_IsParticleSystemValid( ¢->buildablePS ) ) - { - cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDamagedPS ); - - if( CG_IsParticleSystemValid( ¢->buildablePS ) ) - { - CG_SetAttachmentCent( ¢->buildablePS->attachment, cent ); - CG_AttachToCent( ¢->buildablePS->attachment ); - } - } - else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( ¢->buildablePS ) ) - CG_DestroyParticleSystem( ¢->buildablePS ); - } - else if( team == BIT_ALIENS ) - { - if( healthFrac < 0.33f && !CG_IsParticleSystemValid( ¢->buildablePS ) ) - { - cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDamagedPS ); - - if( CG_IsParticleSystemValid( ¢->buildablePS ) ) - { - CG_SetAttachmentCent( ¢->buildablePS->attachment, cent ); - CG_SetParticleSystemNormal( cent->buildablePS, es->origin2 ); - CG_AttachToCent( ¢->buildablePS->attachment ); - } - } - else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( ¢->buildablePS ) ) - CG_DestroyParticleSystem( ¢->buildablePS ); - } -} - - -#define HEALTH_BAR_WIDTH 50.0f -#define HEALTH_BAR_HEIGHT 5.0f - -/* -================== -CG_BuildableHealthBar -================== -*/ -static void CG_BuildableHealthBar( centity_t *cent ) -{ - vec3_t origin, origin2, down, right, back, downLength, rightLength; - float rimWidth = HEALTH_BAR_HEIGHT / 15.0f; - float doneWidth, leftWidth, progress; - int health; - qhandle_t shader; - entityState_t *es; - vec3_t mins, maxs; - - es = ¢->currentState; - - health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - progress = (float)health / B_HEALTH_SCALE; - - if( progress < 0.0f ) - progress = 0.0f; - else if( progress > 1.0f ) - progress = 1.0f; - - if( progress < 0.33f ) - shader = cgs.media.redBuildShader; - else - shader = cgs.media.greenBuildShader; - - doneWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) * progress; - leftWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) - doneWidth; - - VectorCopy( cg.refdef.viewaxis[ 2 ], down ); - VectorInverse( down ); - VectorCopy( cg.refdef.viewaxis[ 1 ], right ); - VectorInverse( right ); - VectorSubtract( cg.refdef.vieworg, cent->lerpOrigin, back ); - VectorNormalize( back ); - VectorCopy( cent->lerpOrigin, origin ); - - BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); - VectorMA( origin, 48.0f, es->origin2, origin ); - VectorMA( origin, -HEALTH_BAR_WIDTH / 2.0f, right, origin ); - VectorMA( origin, maxs[ 0 ] + 8.0f, back, origin ); - - VectorCopy( origin, origin2 ); - VectorScale( right, rimWidth + doneWidth, rightLength ); - VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, rimWidth + doneWidth, right, origin2 ); - VectorScale( right, leftWidth, rightLength ); - VectorScale( down, rimWidth, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, rimWidth + doneWidth, right, origin2 ); - VectorMA( origin2, HEALTH_BAR_HEIGHT - rimWidth, down, origin2 ); - VectorScale( right, leftWidth, rightLength ); - VectorScale( down, rimWidth, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, HEALTH_BAR_WIDTH - rimWidth, right, origin2 ); - VectorScale( right, rimWidth, rightLength ); - VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - if( !( es->generic1 & B_POWERED_TOGGLEBIT ) && - BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS ) - { - VectorMA( origin, 15.0f, right, origin2 ); - VectorMA( origin2, HEALTH_BAR_HEIGHT + 5.0f, down, origin2 ); - VectorScale( right, HEALTH_BAR_WIDTH / 2.0f - 5.0f, rightLength ); - VectorScale( down, HEALTH_BAR_WIDTH / 2.0f - 5.0f, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, cgs.media.noPowerShader ); - } -} - -#define BUILDABLE_SOUND_PERIOD 500 - -/* -================== -CG_Buildable -================== -*/ -void CG_Buildable( centity_t *cent ) -{ - refEntity_t ent; - entityState_t *es = ¢->currentState; - vec3_t angles; - vec3_t surfNormal, xNormal, mins, maxs; - vec3_t refNormal = { 0.0f, 0.0f, 1.0f }; - float rotAngle; - buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex ); - float scale; - int health; - float healthScale; - - //must be before EF_NODRAW check - if( team == BIT_ALIENS ) - CG_Creep( cent ); - - // if set to invisible, skip - if( es->eFlags & EF_NODRAW ) - { - if( CG_IsParticleSystemValid( ¢->buildablePS ) ) - CG_DestroyParticleSystem( ¢->buildablePS ); - - return; - } - - memset ( &ent, 0, sizeof( ent ) ); - - VectorCopy( cent->lerpOrigin, ent.origin ); - VectorCopy( cent->lerpOrigin, ent.oldorigin ); - VectorCopy( cent->lerpOrigin, ent.lightingOrigin ); - - VectorCopy( es->origin2, surfNormal ); - - VectorCopy( es->angles, angles ); - BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); - - if( es->pos.trType == TR_STATIONARY ) - CG_PositionAndOrientateBuildable( angles, ent.origin, surfNormal, es->number, - mins, maxs, ent.axis, ent.origin ); - - //offset on the Z axis if required - VectorMA( ent.origin, BG_FindZOffsetForBuildable( es->modelindex ), surfNormal, ent.origin ); - - VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all - VectorCopy( ent.origin, ent.lightingOrigin ); - - ent.hModel = cg_buildables[ es->modelindex ].models[ 0 ]; - - if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) - { - sfxHandle_t prebuildSound = cgs.media.humanBuildablePrebuild; - - if( team == BIT_HUMANS ) - { - ent.customShader = cgs.media.humanSpawningShader; - prebuildSound = cgs.media.humanBuildablePrebuild; - } - else if( team == BIT_ALIENS ) - prebuildSound = cgs.media.alienBuildablePrebuild; - - trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound ); - } - - CG_BuildableAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp ); - - //rescale the model - scale = BG_FindModelScaleForBuildable( es->modelindex ); - - 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 ); - - CrossProduct( surfNormal, refNormal, xNormal ); - VectorNormalize( xNormal ); - rotAngle = RAD2DEG( acos( DotProduct( surfNormal, refNormal ) ) ); - - //turret barrel bit - if( cg_buildables[ es->modelindex ].models[ 1 ] ) - { - refEntity_t turretBarrel; - vec3_t flatAxis[ 3 ]; - - memset( &turretBarrel, 0, sizeof( turretBarrel ) ); - - turretBarrel.hModel = cg_buildables[ es->modelindex ].models[ 1 ]; - - CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" ); - VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin ); - AnglesToAxis( es->angles2, flatAxis ); - - RotatePointAroundVector( turretBarrel.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle ); - RotatePointAroundVector( turretBarrel.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle ); - RotatePointAroundVector( turretBarrel.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle ); - - turretBarrel.oldframe = ent.oldframe; - turretBarrel.frame = ent.frame; - turretBarrel.backlerp = ent.backlerp; - - turretBarrel.customShader = ent.customShader; - - if( scale != 1.0f ) - { - VectorScale( turretBarrel.axis[ 0 ], scale, turretBarrel.axis[ 0 ] ); - VectorScale( turretBarrel.axis[ 1 ], scale, turretBarrel.axis[ 1 ] ); - VectorScale( turretBarrel.axis[ 2 ], scale, turretBarrel.axis[ 2 ] ); - - turretBarrel.nonNormalizedAxes = qtrue; - } - else - turretBarrel.nonNormalizedAxes = qfalse; - - trap_R_AddRefEntityToScene( &turretBarrel ); - } - - //turret barrel bit - if( cg_buildables[ es->modelindex ].models[ 2 ] ) - { - refEntity_t turretTop; - vec3_t flatAxis[ 3 ]; - vec3_t swivelAngles; - - memset( &turretTop, 0, sizeof( turretTop ) ); - - VectorCopy( es->angles2, swivelAngles ); - swivelAngles[ PITCH ] = 0.0f; - - turretTop.hModel = cg_buildables[ es->modelindex ].models[ 2 ]; - - CG_PositionRotatedEntityOnTag( &turretTop, &ent, ent.hModel, "tag_turret" ); - VectorCopy( cent->lerpOrigin, turretTop.lightingOrigin ); - AnglesToAxis( swivelAngles, flatAxis ); - - RotatePointAroundVector( turretTop.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle ); - RotatePointAroundVector( turretTop.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle ); - RotatePointAroundVector( turretTop.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle ); - - turretTop.oldframe = ent.oldframe; - turretTop.frame = ent.frame; - turretTop.backlerp = ent.backlerp; - - turretTop.customShader = ent.customShader; - - if( scale != 1.0f ) - { - VectorScale( turretTop.axis[ 0 ], scale, turretTop.axis[ 0 ] ); - VectorScale( turretTop.axis[ 1 ], scale, turretTop.axis[ 1 ] ); - VectorScale( turretTop.axis[ 2 ], scale, turretTop.axis[ 2 ] ); - - turretTop.nonNormalizedAxes = qtrue; - } - else - turretTop.nonNormalizedAxes = qfalse; - - trap_R_AddRefEntityToScene( &turretTop ); - } - - switch( cg.predictedPlayerState.weapon ) - { - case WP_ABUILD: - case WP_ABUILD2: - case WP_HBUILD: - case WP_HBUILD2: - if( BG_FindTeamForBuildable( es->modelindex ) == - BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) ) - CG_BuildableHealthBar( cent ); - break; - - default: - break; - } - - //weapon effects for turrets - if( es->eFlags & EF_FIRING ) - { - weaponInfo_t *weapon = &cg_weapons[ es->weapon ]; - - if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME || - BG_FindProjTypeForBuildable( es->modelindex ) == WP_TESLAGEN ) - { - if( weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ] || - weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ] || - weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] ) - { - trap_R_AddLightToScene( cent->lerpOrigin, 300 + ( rand( ) & 31 ), - weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ], - weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ], - weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] ); - } - } - - if( weapon->wim[ WPM_PRIMARY ].firingSound ) - { - trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, - weapon->wim[ WPM_PRIMARY ].firingSound ); - } - else if( weapon->readySound ) - trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, weapon->readySound ); - } - - health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - healthScale = (float)health / B_HEALTH_SCALE; - - if( healthScale < cent->lastBuildableHealthScale && ( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) - { - if( cent->lastBuildableDamageSoundTime + BUILDABLE_SOUND_PERIOD < cg.time ) - { - if( team == BIT_HUMANS ) - { - int i = rand( ) % 4; - trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.humanBuildableDamage[ i ] ); - } - else if( team == BIT_ALIENS ) - trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienBuildableDamage ); - - cent->lastBuildableDamageSoundTime = cg.time; - } - } - - cent->lastBuildableHealthScale = healthScale; - - //smoke etc for damaged buildables - CG_BuildableParticleEffects( cent ); -} |