summaryrefslogtreecommitdiff
path: root/src/cgame/cg_buildable.c
diff options
context:
space:
mode:
authorenneract <trem.redman@gmail.com>2014-02-25 13:03:43 +0100
committerenneract <trem.redman@gmail.com>2014-02-25 13:03:43 +0100
commitdac3d3127fc94231bdde0c0822bb12de01e9e836 (patch)
tree17829bc1a1b0ddb2d49421c5ea0114b4c2eff436 /src/cgame/cg_buildable.c
parentcd9f8731a13a29d51a401f67ec2aa0b8962e01c8 (diff)
0.1.7
Diffstat (limited to 'src/cgame/cg_buildable.c')
-rw-r--r--src/cgame/cg_buildable.c682
1 files changed, 404 insertions, 278 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
index 0c851b0..5646f90 100644
--- a/src/cgame/cg_buildable.c
+++ b/src/cgame/cg_buildable.c
@@ -45,6 +45,77 @@ char *cg_buildableSoundNames[ MAX_BUILDABLE_ANIMATIONS ] =
static sfxHandle_t defaultAlienSounds[ MAX_BUILDABLE_ANIMATIONS ];
static sfxHandle_t defaultHumanSounds[ MAX_BUILDABLE_ANIMATIONS ];
+/*
+======================
+CG_RenderCuboid
+
+Render a cuboid with proper lighting and UV maps
+======================
+*/
+static void CG_RenderCuboid_Face( vec3_t a, vec3_t b, vec3_t c, vec3_t d,
+ int da, int db,
+ vec4_t color,
+ float texscale, qhandle_t shader )
+{
+ polyVert_t verts[ 4 ];
+
+ VectorCopy( d, verts[ 0 ].xyz );
+ verts[ 0 ].st[ 0 ] = d[ da ] * texscale;
+ verts[ 0 ].st[ 1 ] = d[ db ] * texscale;
+ Vector4Copy( color, verts[ 0 ].modulate );
+ VectorCopy( c, verts[ 1 ].xyz );
+ verts[ 1 ].st[ 0 ] = c[ da ] * texscale;
+ verts[ 1 ].st[ 1 ] = c[ db ] * texscale;
+ Vector4Copy( color, verts[ 1 ].modulate );
+ VectorCopy( b, verts[ 2 ].xyz );
+ verts[ 2 ].st[ 0 ] = b[ da ] * texscale;
+ verts[ 2 ].st[ 1 ] = b[ db ] * texscale;
+ Vector4Copy( color, verts[ 2 ].modulate );
+ VectorCopy( a, verts[ 3 ].xyz );
+ verts[ 3 ].st[ 0 ] = a[ da ] * texscale;
+ verts[ 3 ].st[ 1 ] = a[ db ] * texscale;
+ Vector4Copy( color, verts[ 3 ].modulate );
+
+ trap_R_AddPolyToScene( shader, 4, verts );
+}
+
+static void CG_RenderCuboid( vec3_t mins, vec3_t maxs, float texscale, qhandle_t shader )
+{
+ int i;
+ vec3_t midpoint, ambient, directed, idc;
+ vec4_t color = { 255.0f, 255.0f, 255.0f, 255.0f };
+ vec3_t ppp, ppn, pnp, pnn, npp, npn, nnp, nnn;
+
+ //lighting
+ VectorAdd( mins, maxs, midpoint );
+ VectorScale( midpoint, 0.5f, midpoint );
+ trap_R_LightForPoint( midpoint, ambient, directed, idc );
+ VectorAdd( ambient, directed, color );
+ for( i = 0; i < 3; i++ )
+ if( color[ i ] > 255.0f )
+ color[ i ] = 255.0f;
+
+ //vertices
+ VectorSet( ppp, maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] );
+ VectorSet( ppn, maxs[ 0 ], maxs[ 1 ], mins[ 2 ] );
+ VectorSet( pnp, maxs[ 0 ], mins[ 1 ], maxs[ 2 ] );
+ VectorSet( pnn, maxs[ 0 ], mins[ 1 ], mins[ 2 ] );
+ VectorSet( npp, mins[ 0 ], maxs[ 1 ], maxs[ 2 ] );
+ VectorSet( npn, mins[ 0 ], maxs[ 1 ], mins[ 2 ] );
+ VectorSet( nnp, mins[ 0 ], mins[ 1 ], maxs[ 2 ] );
+ VectorSet( nnn, mins[ 0 ], mins[ 1 ], mins[ 2 ] );
+
+ //faces
+ //+-x
+ CG_RenderCuboid_Face( ppn, ppp, pnp, pnn, 1, 2, color, texscale, shader );
+ CG_RenderCuboid_Face( nnn, nnp, npp, npn, 1, 2, color, texscale, shader );
+ //+-y
+ CG_RenderCuboid_Face( ppp, ppn, npn, npp, 0, 2, color, texscale, shader );
+ CG_RenderCuboid_Face( nnp, nnn, pnn, pnp, 0, 2, color, texscale, shader );
+ //+-z
+ CG_RenderCuboid_Face( npp, nnp, pnp, ppp, 0, 1, color, texscale, shader );
+ CG_RenderCuboid_Face( ppn, pnn, nnn, npn, 0, 1, color, texscale, shader );
+}
/*
======================
@@ -1283,7 +1354,6 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
int health;
float x, y;
vec4_t color;
- qboolean powered, marked;
trace_t tr;
float d;
buildStat_t *bs;
@@ -1378,8 +1448,8 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
}
}
- if(cuboid)
- visible=qtrue;
+ if( cuboid )
+ visible = qtrue;
// hack to make the kit obscure view
if( cg_drawGun.integer && visible &&
@@ -1429,13 +1499,13 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
else if( healthScale > 1.0f )
healthScale = 1.0f;
- if(cuboid)
+ if( cuboid )
{
- x=320;
- y=240;
- d=Distance(cg.refdef.vieworg,trac);
- if(d<64.0f)
- d=64.0f;
+ x = 320;
+ y = 240;
+ d = Distance( cg.refdef.vieworg, trac );
+ if( d < 64.0f )
+ d = 64.0f ;
}
else
if( !CG_WorldToScreen( origin, &x, &y ) )
@@ -1454,9 +1524,6 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
// this is fudged to get the width/height in the cfg to be more realistic
scale = ( picH / d ) * 3;
- powered = es->eFlags & EF_B_POWERED;
- marked = es->eFlags & EF_B_MARKED;
-
picH *= scale;
picW *= scale;
picX -= ( picW * 0.5f );
@@ -1527,20 +1594,21 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
}
trap_R_SetColor( color );
- if( !powered )
+
{
float pX;
-
+
pX = picX + ( subH * bs->horizontalMargin );
- CG_DrawPic( pX, subY, subH, subH, bs->noPowerShader );
- }
-
- if( marked )
- {
- float mX;
-
- mX = picX + picW - ( subH * bs->horizontalMargin ) - subH;
- CG_DrawPic( mX, subY, subH, subH, bs->markedShader );
+
+ if( BG_Buildable( es->modelindex, NULL )->team == TEAM_HUMANS )
+ {
+ float offs = 2000.0f / d;
+ CG_DrawPic( pX - offs, subY - offs,
+ subH + 2.0f * offs, subH + 2.0f * offs,
+ CG_BuildablePowerStatusIcon( es ) );
+ }
+ else if( !( es->eFlags & EF_B_POWERED ) )
+ CG_DrawPic( pX, subY, subH, subH, bs->noPowerShader );
}
//NOTE: dont use CG_DrawField, too few digits
@@ -1555,19 +1623,22 @@ static void CG_BuildableStatusDisplay( centity_t *cent, qboolean cuboid, vec3_t
if( health > 0 && healthPoints < 1 )
healthPoints = 1;
- Com_sprintf(buf,sizeof(buf),"%i",healthPoints);
- bufl=strlen(buf);
- cW=subH*cgDC.aspectScale;
- cH=subH;
- nX=picX+picW*0.5f-cW*bufl*0.5f;
+ Com_sprintf( buf, sizeof( buf ), "%i", healthPoints );
+ bufl = strlen(buf);
+ cW = subH*cgDC.aspectScale;
+ cH = subH;
+ nX = picX + picW * 0.5f - cW * bufl * 0.5f;
- for(i=0;i<bufl;i++)
+ for( i = 0; i < bufl; i++ )
{
- if(buf[i]=='-')
- frame=STAT_MINUS;
- else
- frame=buf[i]-'0';
- CG_DrawPic(nX+i*cW,y+bs->verticalMargin-subH*0.5f,cW,cH,cgs.media.numberShaders[frame]);
+ if( buf[ i ] == '-' )
+ frame = STAT_MINUS;
+ else
+ frame = buf[ i ] - '0';
+ CG_DrawPic( nX + i * cW,
+ y + bs->verticalMargin - subH * 0.5f,
+ cW, cH,
+ cgs.media.numberShaders[ frame ] );
}
}
@@ -1620,28 +1691,6 @@ static qboolean CG_PlayerIsBuilder( buildable_t buildable )
/*
==================
-CG_BuildableRemovalPending
-==================
-*/
-static qboolean CG_BuildableRemovalPending( int entityNum )
-{
- int i;
- playerState_t *ps = &cg.snap->ps;
-
- if( !( ps->stats[ STAT_BUILDABLE ] & SB_VALID_TOGGLEBIT ) )
- return qfalse;
-
- for( i = 0; i < MAX_MISC; i++ )
- {
- if( ps->misc[ i ] == entityNum )
- return qtrue;
- }
-
- return qfalse;
-}
-
-/*
-==================
CG_DrawBuildableStatus
==================
*/
@@ -1656,7 +1705,7 @@ void CG_DrawBuildableStatus( void )
trace_t tr;
qboolean cuboid;
- if((cg.predictedPlayerState.stats[STAT_BUILDABLE]&~SB_VALID_TOGGLEBIT)>BA_NONE)
+ if( ( cg.predictedPlayerState.stats[STAT_BUILDABLE] & ~SB_VALID_TOGGLEBIT) > BA_NONE )
return; //hide buildstats if we're placing a buildable
for( i = 0; i < cg.snap->numEntities; i++ )
@@ -1674,8 +1723,8 @@ void CG_DrawBuildableStatus( void )
qsort( buildableList, buildables, sizeof( int ), CG_SortDistance );
for( i = 0; i < buildables; i++ )
{
- cuboid = BG_Buildable(cg_entities[buildableList[i]].currentState.modelindex,NULL)->cuboid;
- if(cuboid && tr.entityNum!=buildableList[i] )
+ cuboid = BG_IsCuboid( cg_entities[ buildableList[ i ] ].currentState.modelindex );
+ if(cuboid && tr.entityNum != buildableList[ i ] )
continue;
CG_BuildableStatusDisplay( &cg_entities[ buildableList[ i ] ], cuboid, tr.endpos );
}
@@ -1713,11 +1762,11 @@ void CG_Buildable( centity_t *cent )
return;
}
- // cuboids use a bit different rendering code !@#CUBOID
+ // cuboids use a bit different rendering code
if( BG_IsCuboid( es->modelindex ) )
{
- qhandle_t texture=0,cracks=0;
- vec3_t dims;
+ qhandle_t texture = 0,cracks = 0;
+ vec3_t dims, mins, maxs;
const cuboidAttributes_t *cuboidAttr;
const cuboidInfo_t *cuboidInfo;
int i, health, sound;
@@ -1733,12 +1782,30 @@ void CG_Buildable( centity_t *cent )
else if ( healthPct < 0.0f )
healthPct = 0.0f;
- if( cuboidInfo->useCracks )
+ if( ( es->eFlags & EF_B_SPAWNED ) && cuboidInfo->useCracks && healthPct < 0.95f )
{
+ float progress;
+ const float o = 1.02f; //md3 rendering is not exact, so render it bigger to compensate
+
if( cuboidInfo->textureCount )
texture = cuboidInfo->textures[ 0 ];
- if( healthPct < 0.75f )
- cracks = cgs.media.cuboidCracks[ (int)( CUBOID_CRACK_TEXTURES - 1 - floor( CUBOID_CRACK_TEXTURES * healthPct ) ) - 1 ];
+
+ memset( &ent, 0, sizeof( ent ) );
+ ent.reType = RT_MODEL;
+ VectorCopy( cent->lerpOrigin, ent.origin );
+
+ ent.axis[0][0]=-dims[0]/2.0f*o;ent.axis[0][1]=0.0f; ent.axis[0][2]=0.0f;
+ ent.axis[1][0]=0.0f; ent.axis[1][1]=-dims[1]/2.0f*o;ent.axis[1][2]=0.0f;
+ ent.axis[2][0]=0.0f; ent.axis[2][1]=0.0f; ent.axis[2][2]=dims[2]/2.0f*o;
+ ent.nonNormalizedAxes = qtrue;
+
+ progress = healthPct;
+
+ ent.customShader = cgs.media.cuboidCracks;
+ ent.shaderTime = 0.001f * cg.time + progress;
+
+ ent.hModel = cgs.media.cuboidModel;
+ trap_R_AddRefEntityToScene( &ent );
}
else
for( i = 0; i < cuboidInfo->textureCount; i++ )
@@ -1750,13 +1817,22 @@ void CG_Buildable( centity_t *cent )
if( !( es->eFlags & EF_B_SPAWNED ) )
{
- sfxHandle_t prebuildSound=cgs.media.humanBuildablePrebuild;
+ sfxHandle_t prebuildSound;
+
if( team == TEAM_HUMANS )
{
- texture = cgs.media.humanSpawningShader;
- prebuildSound = cgs.media.humanBuildablePrebuild;
+ if( es->eFlags & EF_B_POWERED )
+ {
+ texture = cgs.media.humanSpawningShader;
+ prebuildSound = cgs.media.humanBuildablePrebuild;
+ }
+ else
+ {
+ texture = cgs.media.humanUnpoweredSpawningShader;
+ prebuildSound = cgs.media.unpoweredSurgeLoop;
+ }
}
- else if(team==TEAM_ALIENS)
+ else if( team == TEAM_ALIENS )
{
texture = cgs.media.cuboidAlienPrebuild;
prebuildSound = cgs.media.alienBuildablePrebuild;
@@ -1764,24 +1840,11 @@ void CG_Buildable( centity_t *cent )
cracks = 0;
trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound );
}
-
- memset( &ent, 0, sizeof( ent ) );
- ent.reType = RT_MODEL;
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
- VectorCopy( cent->lerpOrigin, ent.lightingOrigin );
-
- //NOTE: don't use CG_PositionAndOrientateBuildable, it screws up everything
- ent.axis[0][0]=-dims[0]/2.0f;ent.axis[0][1]=0.0f; ent.axis[0][2]=0.0f;
- ent.axis[1][0]=0.0f; ent.axis[1][1]=-dims[1]/2.0f;ent.axis[1][2]=0.0f;
- ent.axis[2][0]=0.0f; ent.axis[2][1]=0.0f; ent.axis[2][2]=dims[2]/2.0f;
- ent.nonNormalizedAxes = qtrue;
-
- ent.customShader = texture;
- ent.hModel = cgs.media.cuboidModel;
- trap_R_AddRefEntityToScene( &ent );
- if( cracks )
- CG_DrawCuboid( ent.origin, dims, cracks, 1 );
+
+ BG_CuboidBBox( dims, mins, maxs );
+ VectorAdd( mins, cent->lerpOrigin, mins );
+ VectorAdd( maxs, cent->lerpOrigin, maxs );
+ CG_RenderCuboid( mins, maxs, 0.01f, texture );
if( health < cent->lastBuildableHealth && ( es->eFlags & EF_B_SPAWNED ) )
{
@@ -1795,247 +1858,253 @@ void CG_Buildable( centity_t *cent )
}
}
else
- {
-
- memset ( &ent, 0, sizeof( ent ) );
+ {
+ memset ( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
- VectorCopy( cent->lerpOrigin, ent.lightingOrigin );
+ VectorCopy( cent->lerpOrigin, ent.origin );
+ VectorCopy( cent->lerpOrigin, ent.oldorigin );
+ VectorCopy( cent->lerpOrigin, ent.lightingOrigin );
- VectorCopy( es->origin2, surfNormal );
+ VectorCopy( es->origin2, surfNormal );
- VectorCopy( es->angles, angles );
- BG_BuildableBoundingBox( es->modelindex, mins, maxs );
+ VectorCopy( es->angles, angles );
+ BG_BuildableBoundingBox( es->modelindex, mins, maxs );
- if( es->pos.trType == TR_STATIONARY )
- {
- // Positioning a buildable involves potentially up to two traces, and
- // seeing as buildables rarely move, we cache the results and recalculate
- // only if the buildable moves or changes orientation
- if( VectorCompare( cent->buildableCache.cachedOrigin, cent->lerpOrigin ) &&
- VectorCompare( cent->buildableCache.cachedNormal, surfNormal ) )
- {
- VectorCopy( cent->buildableCache.axis[ 0 ], ent.axis[ 0 ] );
- VectorCopy( cent->buildableCache.axis[ 1 ], ent.axis[ 1 ] );
- VectorCopy( cent->buildableCache.axis[ 2 ], ent.axis[ 2 ] );
- VectorCopy( cent->buildableCache.origin, ent.origin );
- }
- else
+ if( es->pos.trType == TR_STATIONARY )
{
- CG_PositionAndOrientateBuildable( angles, ent.origin, surfNormal,
- es->number, mins, maxs, ent.axis,
- ent.origin, qfalse );
- VectorCopy( ent.axis[ 0 ], cent->buildableCache.axis[ 0 ] );
- VectorCopy( ent.axis[ 1 ], cent->buildableCache.axis[ 1 ] );
- VectorCopy( ent.axis[ 2 ], cent->buildableCache.axis[ 2 ] );
- VectorCopy( ent.origin, cent->buildableCache.origin );
- VectorCopy( cent->lerpOrigin, cent->buildableCache.cachedOrigin );
- VectorCopy( surfNormal, cent->buildableCache.cachedNormal );
+ // Positioning a buildable involves potentially up to two traces, and
+ // seeing as buildables rarely move, we cache the results and recalculate
+ // only if the buildable moves or changes orientation
+ if( VectorCompare( cent->buildableCache.cachedOrigin, cent->lerpOrigin ) &&
+ VectorCompare( cent->buildableCache.cachedNormal, surfNormal ) )
+ {
+ VectorCopy( cent->buildableCache.axis[ 0 ], ent.axis[ 0 ] );
+ VectorCopy( cent->buildableCache.axis[ 1 ], ent.axis[ 1 ] );
+ VectorCopy( cent->buildableCache.axis[ 2 ], ent.axis[ 2 ] );
+ VectorCopy( cent->buildableCache.origin, ent.origin );
+ }
+ else
+ {
+ CG_PositionAndOrientateBuildable( angles, ent.origin, surfNormal,
+ es->number, mins, maxs, ent.axis,
+ ent.origin, qfalse );
+ VectorCopy( ent.axis[ 0 ], cent->buildableCache.axis[ 0 ] );
+ VectorCopy( ent.axis[ 1 ], cent->buildableCache.axis[ 1 ] );
+ VectorCopy( ent.axis[ 2 ], cent->buildableCache.axis[ 2 ] );
+ VectorCopy( ent.origin, cent->buildableCache.origin );
+ VectorCopy( cent->lerpOrigin, cent->buildableCache.cachedOrigin );
+ VectorCopy( surfNormal, cent->buildableCache.cachedNormal );
+ }
}
- }
-
- VectorMA( ent.origin, BG_BuildableConfig( es->modelindex )->zOffset, surfNormal, ent.origin );
-
- VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all
- VectorCopy( ent.origin, ent.lightingOrigin );
+ VectorMA( ent.origin, BG_BuildableConfig( es->modelindex )->zOffset, surfNormal, ent.origin );
+
- ent.hModel = cg_buildables[ es->modelindex ].models[ 0 ];
+ VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all
+ VectorCopy( ent.origin, ent.lightingOrigin );
- if( !( es->eFlags & EF_B_SPAWNED ) )
- {
- sfxHandle_t prebuildSound = cgs.media.humanBuildablePrebuild;
+ ent.hModel = cg_buildables[ es->modelindex ].models[ 0 ];
- if( team == TEAM_HUMANS )
+ if( !( es->eFlags & EF_B_SPAWNED ) )
{
- ent.customShader = cgs.media.humanSpawningShader;
- prebuildSound = cgs.media.humanBuildablePrebuild;
- }
- else if( team == TEAM_ALIENS )
- prebuildSound = cgs.media.alienBuildablePrebuild;
+ sfxHandle_t prebuildSound = cgs.media.humanBuildablePrebuild;
- trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound );
- }
+ if( team == TEAM_HUMANS )
+ {
+ if( es->eFlags & EF_B_POWERED )
+ {
+ ent.customShader = cgs.media.humanSpawningShader;
+ prebuildSound = cgs.media.humanBuildablePrebuild;
+ }
+ else
+ {
+ ent.customShader = cgs.media.humanUnpoweredSpawningShader;
+ prebuildSound = cgs.media.unpoweredSurgeLoop;
+ }
+ }
+ else if( team == TEAM_ALIENS )
+ prebuildSound = cgs.media.alienBuildablePrebuild;
+
+ trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound );
+ }
- CG_BuildableAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp );
+ CG_BuildableAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp );
- //rescale the model
- scale = BG_BuildableConfig( es->modelindex )->modelScale;
+ //rescale the model
+ scale = BG_BuildableConfig( es->modelindex )->modelScale;
- 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 ] );
+ 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;
-
+ ent.nonNormalizedAxes = qtrue;
+ }
+ else
+ ent.nonNormalizedAxes = qfalse;
- if( CG_PlayerIsBuilder( es->modelindex ) && CG_BuildableRemovalPending( es->number ) )
- ent.customShader = cgs.media.redBuildShader;
+ //add to refresh list
+ trap_R_AddRefEntityToScene( &ent );
- //add to refresh list
- trap_R_AddRefEntityToScene( &ent );
+ CrossProduct( surfNormal, refNormal, xNormal );
+ VectorNormalize( xNormal );
+ rotAngle = RAD2DEG( acos( DotProduct( surfNormal, refNormal ) ) );
- 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 ];
- //turret barrel bit
- if( cg_buildables[ es->modelindex ].models[ 1 ] )
- {
- refEntity_t turretBarrel;
- vec3_t flatAxis[ 3 ];
+ memset( &turretBarrel, 0, sizeof( turretBarrel ) );
- memset( &turretBarrel, 0, sizeof( turretBarrel ) );
+ turretBarrel.hModel = cg_buildables[ es->modelindex ].models[ 1 ];
- turretBarrel.hModel = cg_buildables[ es->modelindex ].models[ 1 ];
+ CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" );
+ VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin );
- CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" );
- VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin );
+ {
+ vec3_t interpolated;
+ int i;
- {
- vec3_t interpolated;
- int i;
+ for( i = 0; i < 3 ; i++ )
+ interpolated[ i ] = LerpAngle( es->angles2[ i ], cent->nextState.angles2[ i ], cg.frameInterpolation );
- for( i = 0; i < 3 ; i++ )
- interpolated[ i ] = LerpAngle( es->angles2[ i ], cent->nextState.angles2[ i ], cg.frameInterpolation );
+ AnglesToAxis( interpolated, flatAxis );
+ }
- AnglesToAxis( interpolated, 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 );
- 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.oldframe = ent.oldframe;
- turretBarrel.frame = ent.frame;
- turretBarrel.backlerp = ent.backlerp;
+ turretBarrel.customShader = ent.customShader;
- 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 ] );
- 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;
- turretBarrel.nonNormalizedAxes = qtrue;
+ trap_R_AddRefEntityToScene( &turretBarrel );
}
- else
- turretBarrel.nonNormalizedAxes = qfalse;
-
- if( CG_PlayerIsBuilder( es->modelindex ) && CG_BuildableRemovalPending( es->number ) )
- turretBarrel.customShader = cgs.media.redBuildShader;
- trap_R_AddRefEntityToScene( &turretBarrel );
- }
+ //turret barrel bit
+ if( cg_buildables[ es->modelindex ].models[ 2 ] )
+ {
+ refEntity_t turretTop;
+ vec3_t flatAxis[ 3 ];
+ vec3_t swivelAngles;
- //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 ) );
- memset( &turretTop, 0, sizeof( turretTop ) );
+ VectorCopy( es->angles2, swivelAngles );
+ swivelAngles[ PITCH ] = 0.0f;
- VectorCopy( es->angles2, swivelAngles );
- swivelAngles[ PITCH ] = 0.0f;
+ turretTop.hModel = cg_buildables[ es->modelindex ].models[ 2 ];
- turretTop.hModel = cg_buildables[ es->modelindex ].models[ 2 ];
+ CG_PositionRotatedEntityOnTag( &turretTop, &ent, ent.hModel, "tag_turret" );
+ VectorCopy( cent->lerpOrigin, turretTop.lightingOrigin );
+ AnglesToAxis( swivelAngles, flatAxis );
- 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 );
- 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.oldframe = ent.oldframe;
- turretTop.frame = ent.frame;
- turretTop.backlerp = ent.backlerp;
+ turretTop.customShader = ent.customShader;
- 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 ] );
- 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;
- turretTop.nonNormalizedAxes = qtrue;
+ trap_R_AddRefEntityToScene( &turretTop );
}
- else
- turretTop.nonNormalizedAxes = qfalse;
-
- if( CG_PlayerIsBuilder( es->modelindex ) && CG_BuildableRemovalPending( es->number ) )
- turretTop.customShader = cgs.media.redBuildShader;
- trap_R_AddRefEntityToScene( &turretTop );
- }
-
- //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_Buildable( es->modelindex, NULL )->turretProjType == WP_TESLAGEN )
+ //weapon effects for turrets
+ if( es->eFlags & EF_FIRING )
{
- if( weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ] ||
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ] ||
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] )
+ weaponInfo_t *weapon = &cg_weapons[ es->weapon ];
+
+ if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME ||
+ BG_Buildable( es->modelindex, NULL )->turretProjType == WP_TESLAGEN )
{
- 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 ].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 );
+ 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 );
}
- else if( weapon->readySound )
- trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, weapon->readySound );
- }
-
- //smoke etc for damaged buildables
- CG_BuildableParticleEffects( cent );
-
-
+
+ //smoke etc for damaged buildables
+ CG_BuildableParticleEffects( cent );
+
+
-
- health = es->generic1;
+
+ health = es->generic1;
- if( health < cent->lastBuildableHealth &&
- ( es->eFlags & EF_B_SPAWNED ) )
- {
- if( cent->lastBuildableDamageSoundTime + BUILDABLE_SOUND_PERIOD < cg.time )
+ if( health < cent->lastBuildableHealth &&
+ ( es->eFlags & EF_B_SPAWNED ) )
{
- if( team == TEAM_HUMANS )
+ if( cent->lastBuildableDamageSoundTime + BUILDABLE_SOUND_PERIOD < cg.time )
{
- int i = rand( ) % 4;
- trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.humanBuildableDamage[ i ] );
- }
- else if( team == TEAM_ALIENS )
- trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienBuildableDamage );
+ if( team == TEAM_HUMANS )
+ {
+ int i = rand( ) % 4;
+ trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.humanBuildableDamage[ i ] );
+ }
+ else if( team == TEAM_ALIENS )
+ trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienBuildableDamage );
- cent->lastBuildableDamageSoundTime = cg.time;
+ cent->lastBuildableDamageSoundTime = cg.time;
+ }
}
- }
-
- cent->lastBuildableHealth = health;
+ cent->lastBuildableHealth = health;
} //if (is a cuboid)
+
+
+ // play a loop if there's not enough power for it to build / activate
+ if( ( !( es->eFlags & EF_B_SPAWNED ) &&
+ !( es->eFlags & EF_B_POWERED ) ) ||
+ ( ( BG_Buildable( es->modelindex, NULL )->requiresPower ||
+ es->modelindex != BA_H_REPEATER ) &&
+ !( es->eFlags & EF_B_POWERED ) &&
+ ( es->eFlags & EF_B_SURGE ) ) )
+ trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, cgs.media.unpoweredSurgeLoop );
}
char cuboidInfo[128];
@@ -2049,17 +2118,21 @@ Draw the cuboid info string generated by CG_Cuboid_Info.
*/
void CG_Cuboid_DrawInfo(void)
{
- float x,y,w,h,s=0.5f;
+ float x,y,w,h,s=0.5f;
+
+ // disabled by default (replaced by ckit's display)
+ if( !cg_drawCuboidInfo.integer )
+ return;
- if(!BG_Buildable(cg.predictedPlayerState.stats[STAT_BUILDABLE]&~SB_VALID_TOGGLEBIT,NULL)->cuboid)
- return;
+ if( !BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, NULL )->cuboid )
+ return;
- w=UI_Text_Width(cuboidInfo,s);
- h=UI_Text_Height(cuboidInfo,s);
- x=320.0f-w/2.0f+cg_cuboidInfoX.value;
- y=240.0f-h/2.0f+cg_cuboidInfoY.value;
+ w= UI_Text_Width( cuboidInfo, s );
+ h= UI_Text_Height( cuboidInfo, s );
+ x= 320.0f - w / 2.0f + cg_cuboidInfoX.value;
+ y= 240.0f - h / 2.0f + cg_cuboidInfoY.value;
- UI_Text_Paint(x,y,s,colorWhite,cuboidInfo,0,0,ITEM_TEXTSTYLE_SHADOWEDMORE);
+ UI_Text_Paint( x, y, s, colorWhite, cuboidInfo, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE );
}
/*
@@ -2076,6 +2149,9 @@ void CG_Cuboid_Info(void)
const buildableAttributes_t *attr;
int axis=cg_cuboidResizeAxis.integer;
+ if( !cg_drawCuboidInfo.integer )
+ return;
+
attr=BG_Buildable(cg.predictedPlayerState.stats[STAT_BUILDABLE]&~SB_VALID_TOGGLEBIT,cg.cuboidSelection);
Com_sprintf(cuboidInfo,sizeof(cuboidInfo),
"^7[^3%c^7] | ^%c%.1f^7x^%c%.1f^7x^%c%.1f ^7| ^3%i^7HP | ^3%i^7ms | ^3%i^7BP",
@@ -2342,3 +2418,53 @@ void CG_CuboidAttack_f(void)
trap_SendClientCommand( va( "%s", CG_Argv(0) ) );
}
+/*
+======================
+CG_BuildablePowerStatusIcon
+
+Figures out the power status icon for a buildable
+======================
+*/
+qhandle_t CG_BuildablePowerStatusIcon( entityState_t *es )
+{
+ qboolean powered = ( es->eFlags & EF_B_POWERED );
+
+ if( !( es->eFlags & EF_B_SPAWNED ) )
+ {
+ if( powered )
+ return cgs.media.ckit_icon_surge;
+ else
+ return cgs.media.ckit_icon_nosurge;
+ }
+
+ if( BG_Buildable( es->modelindex, NULL )->isPowerSource ||
+ es->modelindex == BA_H_REPEATER )
+ {
+ qboolean active = ( es->eFlags & EF_B_SURGE );
+
+ if( !active )
+ return cgs.media.ckit_icon_off;
+ else if( powered )
+ return cgs.media.ckit_icon_power;
+ else
+ return cgs.media.ckit_icon_nopower;
+ }
+ else
+ {
+ if( !( es->eFlags & EF_B_SURGE ) )
+ {
+ if( powered )
+ return cgs.media.ckit_icon_power;
+ else
+ return cgs.media.ckit_icon_nopower;
+ }
+ else
+ {
+ if( powered )
+ return cgs.media.ckit_icon_surge;
+ else
+ return cgs.media.ckit_icon_nosurge;
+ }
+ }
+ return 0;
+}