From 426e5df1d31265646f193c5f345efcdd6fc93779 Mon Sep 17 00:00:00 2001 From: "Tony J. White" Date: Wed, 21 Mar 2007 22:02:57 +0000 Subject: * new 2D status bars for buildings * spawns never show the ¨no power¨ icon since they don't need reactor/overmind * alien buildings that require the overmind to function will now show the "no power¨ icon when the overmind is down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cgame/cg_buildable.c | 383 ++++++++++++++++++++++++++++++++++++++++++++--- src/cgame/cg_draw.c | 7 +- src/cgame/cg_local.h | 29 +++- src/cgame/cg_main.c | 4 +- src/game/bg_misc.c | 35 +++++ src/game/bg_public.h | 2 + src/game/g_buildable.c | 21 ++- 7 files changed, 451 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index 0bf6889c..e7b4d853 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -736,9 +736,145 @@ static void CG_BuildableParticleEffects( centity_t *cent ) } } -#define STATUS_FADE_TIME 200 -#define STATUS_MAX_VIEW_DIST 600.0f +void CG_BuildableStatusParse( const char *filename, buildStat_t *bs ) +{ + pc_token_t token; + int handle; + const char *s; + int i; + float f; + vec4_t c; + + handle = trap_Parse_LoadSource( filename ); + if( !handle ) + return; + while( 1 ) + { + if( !trap_Parse_ReadToken( handle, &token ) ) + break; + if( !Q_stricmp( token.string, "frameShader" ) ) + { + if( PC_String_Parse( handle, &s ) ) + bs->frameShader = trap_R_RegisterShader( s ); + continue; + } + else if( !Q_stricmp( token.string, "overlayShader" ) ) + { + if( PC_String_Parse( handle, &s ) ) + bs->overlayShader = trap_R_RegisterShader( s ); + continue; + } + else if( !Q_stricmp( token.string, "noPowerShader" ) ) + { + if( PC_String_Parse( handle, &s ) ) + bs->noPowerShader = trap_R_RegisterShader( s ); + continue; + } + else if( !Q_stricmp( token.string, "markedShader" ) ) + { + if( PC_String_Parse( handle, &s ) ) + bs->markedShader = trap_R_RegisterShader( s ); + continue; + } + else if( !Q_stricmp( token.string, "healthSevereColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->healthSevereColor ); + continue; + } + else if( !Q_stricmp( token.string, "healthHighColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->healthHighColor ); + continue; + } + else if( !Q_stricmp( token.string, "healthElevatedColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->healthElevatedColor ); + continue; + } + else if( !Q_stricmp( token.string, "healthGuardedColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->healthGuardedColor ); + continue; + } + else if( !Q_stricmp( token.string, "healthLowColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->healthLowColor ); + continue; + } + else if( !Q_stricmp( token.string, "foreColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->foreColor ); + continue; + } + else if( !Q_stricmp( token.string, "backColor" ) ) + { + if( PC_Color_Parse( handle, &c ) ) + Vector4Copy( c, bs->backColor ); + continue; + } + else if( !Q_stricmp( token.string, "frameHeight" ) ) + { + if( PC_Int_Parse( handle, &i ) ) + bs->frameHeight = i; + continue; + } + else if( !Q_stricmp( token.string, "frameWidth" ) ) + { + if( PC_Int_Parse( handle, &i ) ) + bs->frameWidth = i; + continue; + } + else if( !Q_stricmp( token.string, "healthPadding" ) ) + { + if( PC_Int_Parse( handle, &i ) ) + bs->healthPadding = i; + continue; + } + else if( !Q_stricmp( token.string, "overlayHeight" ) ) + { + if( PC_Int_Parse( handle, &i ) ) + bs->overlayHeight = i; + continue; + } + else if( !Q_stricmp( token.string, "overlayWidth" ) ) + { + if( PC_Int_Parse( handle, &i ) ) + bs->overlayWidth = i; + continue; + } + else if( !Q_stricmp( token.string, "verticalMargin" ) ) + { + if( PC_Float_Parse( handle, &f ) ) + bs->verticalMargin = f; + continue; + } + else if( !Q_stricmp( token.string, "horizontalMargin" ) ) + { + if( PC_Float_Parse( handle, &f ) ) + bs->horizontalMargin = f; + continue; + } + else + { + Com_Printf("CG_BuildableStatusParse: unknown token %s in %s\n", + token.string, filename ); + bs->loaded = qfalse; + return; + } + } + bs->loaded = qtrue; +} + +#define STATUS_FADE_TIME 200 +#define STATUS_MAX_VIEW_DIST 900.0f +#define STATUS_PEEK_DIST 20 /* ================== CG_BuildableStatusDisplay @@ -751,25 +887,104 @@ static void CG_BuildableStatusDisplay( centity_t *cent ) float healthScale; int health; float x, y; - char s[ MAX_STRING_CHARS ] = { 0 }; - int w; - vec4_t color = { 1.0f, 1.0f, 1.0f, 1.0f }; + vec4_t color; qboolean powered, marked; trace_t tr; float d; + buildStat_t *bs; + int i, j; + int entNum; + vec3_t trOrigin; + vec3_t right; + qboolean visible = qfalse; + vec3_t mins, maxs; + entityState_t *hit; - CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, cg.refdef.vieworg, - cent->currentState.number, MASK_SOLID ); + if( BG_FindTeamForBuildable( es->modelindex ) == BIT_ALIENS ) + bs = &cgs.alienBuildStat; + else + bs = &cgs.humanBuildStat; + + if( !bs->loaded ) + return; + d = Distance( cent->lerpOrigin, cg.refdef.vieworg ); + if( d > STATUS_MAX_VIEW_DIST ) + return; + + Vector4Copy( bs->foreColor, color ); + + // trace for center point + BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); + + VectorCopy( cent->lerpOrigin, origin ); + + // center point + origin[ 2 ] += mins[ 2 ]; + origin[ 2 ] += ( abs( mins[ 2 ] ) + abs( maxs[ 2 ] ) ) / 2; + + entNum = cg.predictedPlayerState.clientNum; + + // if first try fails, step left, step right + for( j = 0; j < 3; j++ ) + { + VectorCopy( cg.refdef.vieworg, trOrigin ); + switch( j ) + { + case 1: + // step right + AngleVectors( cg.refdefViewAngles, NULL, right, NULL ); + VectorMA( trOrigin, STATUS_PEEK_DIST, right, trOrigin ); + break; + case 2: + // step left + AngleVectors( cg.refdefViewAngles, NULL, right, NULL ); + VectorMA( trOrigin, -STATUS_PEEK_DIST, right, trOrigin ); + break; + default: + break; + } + // look through up to 3 players and/or transparent buildables + for( i = 0; i < 3; i++ ) + { + CG_Trace( &tr, trOrigin, NULL, NULL, origin, entNum, MASK_SHOT ); + if( tr.entityNum == cent->currentState.number ) + { + visible = qtrue; + break; + } + + if( tr.entityNum == ENTITYNUM_WORLD ) + break; - if( ( tr.fraction < 1.0f || d > STATUS_MAX_VIEW_DIST ) && - cent->buildableStatus.visible ) + hit = &cg_entities[ tr.entityNum ].currentState; + + if( tr.entityNum < MAX_CLIENTS || ( hit->eType == ET_BUILDABLE && + ( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) || + BG_FindTransparentTestForBuildable( hit->modelindex ) ) ) ) + { + entNum = tr.entityNum; + VectorCopy( tr.endpos, trOrigin ); + } + else + break; + } + } + // hack to make the kit obscure view + if( cg_drawGun.integer && visible && + cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS && + CG_WorldToScreen( origin, &x, &y ) ) + { + if( x > 450 && y > 290 ) + visible = qfalse; + } + + if( !visible && cent->buildableStatus.visible ) { cent->buildableStatus.visible = qfalse; cent->buildableStatus.lastTime = cg.time; } - else if( ( tr.fraction == 1.0f && d <= STATUS_MAX_VIEW_DIST ) && - !cent->buildableStatus.visible ) + else if( visible && !cent->buildableStatus.visible ) { cent->buildableStatus.visible = qtrue; cent->buildableStatus.lastTime = cg.time; @@ -794,33 +1009,152 @@ static void CG_BuildableStatusDisplay( centity_t *cent ) health = es->generic1 & B_HEALTH_MASK; healthScale = (float)health / B_HEALTH_MASK; - if( healthScale < 0.0f ) + if( health > 0 && healthScale < 0.01f ) + healthScale = 0.01f; + else if( healthScale < 0.0f ) healthScale = 0.0f; else if( healthScale > 1.0f ) healthScale = 1.0f; - VectorCopy( cent->lerpOrigin, origin ); - if( CG_WorldToScreen( origin, &x, &y ) ) { + float picH = bs->frameHeight; + float picW = bs->frameWidth; + float picX = x; + float picY = y; + float scale; + float subH, subY; + vec4_t frameColor; + + // this is fudged to get the width/height in the cfg to be more realistic + scale = ( picH / d ) * 3; + powered = es->generic1 & B_POWERED_TOGGLEBIT; marked = es->generic1 & B_MARKED_TOGGLEBIT; - //FIXME: crappy mock-up for the time being... - Com_sprintf( s, MAX_STRING_CHARS, "%d%%", (int)(healthScale * 100) ); + picH *= scale; + picW *= scale; + picX -= ( picW * 0.5f ); + picY -= ( picH * 0.5f ); + + // sub-elements such as icons and number + subH = picH - ( picH * bs->verticalMargin ); + subY = picY + ( picH * 0.5f ) - ( subH * 0.5f ); + + if( bs->frameShader ) + { + Vector4Copy( bs->backColor, frameColor ); + frameColor[ 3 ] = color[ 3 ]; + trap_R_SetColor( frameColor ); + CG_DrawPic( picX, picY, picW, picH, bs->frameShader ); + trap_R_SetColor( NULL ); + } + + if( health > 0 ) + { + float hX, hY, hW, hH; + vec4_t healthColor; + + hX = picX + ( bs->healthPadding * scale ); + hY = picY + ( bs->healthPadding * scale ); + hH = picH - ( bs->healthPadding * 2.0f * scale ); + hW = picW * healthScale - ( bs->healthPadding * 2.0f * scale ); + + if( healthScale == 1.0f ) + Vector4Copy( bs->healthLowColor, healthColor ); + else if( healthScale >= 0.75f ) + Vector4Copy( bs->healthGuardedColor, healthColor ); + else if( healthScale >= 0.50f ) + Vector4Copy( bs->healthElevatedColor, healthColor ); + else if( healthScale >= 0.25f ) + Vector4Copy( bs->healthHighColor, healthColor ); + else + Vector4Copy( bs->healthSevereColor, healthColor ); + + healthColor[ 3 ] = color[ 3 ]; + trap_R_SetColor( healthColor ); + + CG_DrawPic( hX, hY, hW, hH, cgs.media.whiteShader ); + trap_R_SetColor( NULL ); + } + + if( bs->overlayShader ) + { + float oW = bs->overlayWidth; + float oH = bs->overlayHeight; + float oX = x; + float oY = y; + + oH *= scale; + oW *= scale; + oX -= ( oW * 0.5f ); + oY -= ( oH * 0.5f ); + + trap_R_SetColor( frameColor ); + CG_DrawPic( oX, oY, oW, oH, bs->overlayShader ); + trap_R_SetColor( NULL ); + } + + trap_R_SetColor( color ); + if( !powered ) + { + float pX; - if( BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS && !powered ) - Q_strcat( s, MAX_STRING_CHARS, " P" ); + pX = picX + ( subH * bs->horizontalMargin ); + CG_DrawPic( pX, subY, subH, subH, bs->noPowerShader ); + } if( marked ) - Q_strcat( s, MAX_STRING_CHARS, " X" ); + { + float mX; - w = CG_Text_Width( s, 0.5f, 0 ); + mX = picX + picW - ( subH * bs->horizontalMargin ) - subH; + CG_DrawPic( mX, subY, subH, subH, bs->markedShader ); + } - CG_Text_Paint( x - w / 2, y, 0.5f, color, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); + { + float nX; + int healthMax; + int healthPoints; + + healthMax = BG_FindHealthForBuildable( es->modelindex ); + healthPoints = (int)( healthScale * healthMax ); + if( health > 0 && healthPoints < 1 ) + healthPoints = 1; + nX = picX + ( picW * 0.5f ) - 2.0f - ( ( subH * 4 ) * 0.5f ); + + if( healthPoints > 999 ) + nX -= 0.0f; + else if( healthPoints > 99 ) + nX -= subH * 0.5f; + else if( healthPoints > 9 ) + nX -= subH * 1.0f; + else + nX -= subH * 1.5f; + + CG_DrawField( nX, subY, 4, subH, subH, healthPoints ); + } + trap_R_SetColor( NULL ); } } +static int QDECL CG_SortDistance( const void *a, const void *b ) +{ + centity_t *aent, *bent; + float adist, bdist; + + aent = &cg_entities[ *(int *)a ]; + bent = &cg_entities[ *(int *)b ]; + adist = Distance( cg.refdef.vieworg, aent->lerpOrigin ); + bdist = Distance( cg.refdef.vieworg, bent->lerpOrigin ); + if( adist > bdist ) + return -1; + else if( adist < bdist ) + return 1; + else + return 0; +} + /* ================== CG_DrawBuildableStatus @@ -831,6 +1165,8 @@ void CG_DrawBuildableStatus( void ) int i; centity_t *cent; entityState_t *es; + int buildableList[ MAX_ENTITIES_IN_SNAPSHOT ]; + int buildables = 0; switch( cg.predictedPlayerState.weapon ) { @@ -846,8 +1182,11 @@ void CG_DrawBuildableStatus( void ) if( es->eType == ET_BUILDABLE && BG_FindTeamForBuildable( es->modelindex ) == BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) ) - CG_BuildableStatusDisplay( cent ); + buildableList[ buildables++ ] = cg.snap->entities[ i ].number; } + qsort( buildableList, buildables, sizeof( int ), CG_SortDistance ); + for( i = 0; i < buildables; i++ ) + CG_BuildableStatusDisplay( &cg_entities[ buildableList[ i ] ] ); break; default: diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 3245458b..1a96e75f 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -376,12 +376,12 @@ CG_DrawField Draws large numbers for status bar and powerups ============== */ -static void CG_DrawField( int x, int y, int width, int cw, int ch, int value ) +void CG_DrawField( float x, float y, int width, float cw, float ch, int value ) { char num[ 16 ], *ptr; int l; int frame; - int charWidth, charHeight; + float charWidth, charHeight; if( !( charWidth = cw ) ) charWidth = CHAR_WIDTH; @@ -3294,11 +3294,11 @@ static void CG_Draw2D( void ) !( cg.snap->ps.stats[ STAT_STATE ] & SS_HOVELING ) && menu && ( cg.snap->ps.stats[ STAT_HEALTH ] > 0 ) ) { + CG_DrawBuildableStatus( ); if( cg_drawStatus.integer ) Menu_Paint( menu, qtrue ); CG_DrawCrosshair( ); - CG_DrawBuildableStatus( ); } else if( cg_drawStatus.integer ) Menu_Paint( defaultMenu, qtrue ); @@ -3510,3 +3510,4 @@ void CG_DrawActive( stereoFrame_t stereoView ) } + diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index b0ce4b6d..5bebfaf0 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1177,7 +1177,6 @@ typedef struct // buildable shaders qhandle_t greenBuildShader; qhandle_t redBuildShader; - qhandle_t noPowerShader; qhandle_t humanSpawningShader; // disconnect @@ -1273,6 +1272,29 @@ typedef struct qhandle_t upgradeClassIconShader; } cgMedia_t; +typedef struct +{ + qhandle_t frameShader; + qhandle_t overlayShader; + qhandle_t noPowerShader; + qhandle_t markedShader; + vec4_t healthSevereColor; + vec4_t healthHighColor; + vec4_t healthElevatedColor; + vec4_t healthGuardedColor; + vec4_t healthLowColor; + int frameHeight; + int frameWidth; + int healthPadding; + int overlayHeight; + int overlayWidth; + float verticalMargin; + float horizontalMargin; + vec4_t foreColor; + vec4_t backColor; + qboolean loaded; +} buildStat_t; + // The client game static (cgs) structure hold everything // loaded or calculated from the gamestate. It will NOT @@ -1356,6 +1378,9 @@ typedef struct void *capturedItem; qhandle_t activeCursor; + buildStat_t alienBuildStat; + buildStat_t humanBuildStat; + // media cgMedia_t media; } cgs_t; @@ -1598,6 +1623,7 @@ void CG_Text_PaintChar( float x, float y, float width, float height, floa void CG_DrawLoadingScreen( void ); void CG_UpdateMediaFraction( float newFract ); void CG_ResetPainBlend( void ); +void CG_DrawField( float x, float y, int width, float cw, float ch, int value ); // // cg_players.c @@ -1618,6 +1644,7 @@ qboolean CG_AtHighestClass( void ); // void CG_GhostBuildable( buildable_t buildable ); void CG_Buildable( centity_t *cent ); +void CG_BuildableStatusParse( const char *filename, buildStat_t *bs ); void CG_DrawBuildableStatus( void ); void CG_InitBuildables( void ); void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir ); diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index f5402537..8647df8f 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -788,7 +788,6 @@ static void CG_RegisterGraphics( void ) //TA: building shaders cgs.media.greenBuildShader = trap_R_RegisterShader("gfx/misc/greenbuild" ); cgs.media.redBuildShader = trap_R_RegisterShader("gfx/misc/redbuild" ); - cgs.media.noPowerShader = trap_R_RegisterShader("gfx/misc/nopower" ); cgs.media.humanSpawningShader = trap_R_RegisterShader("models/buildables/telenode/rep_cyl" ); for( i = 0; i < 8; i++ ) @@ -824,6 +823,9 @@ static void CG_RegisterGraphics( void ) cgs.media.alienBleedPS = CG_RegisterParticleSystem( "alienBleedPS" ); cgs.media.humanBleedPS = CG_RegisterParticleSystem( "humanBleedPS" ); + CG_BuildableStatusParse( "ui/assets/human/buildstat.cfg", &cgs.humanBuildStat ); + CG_BuildableStatusParse( "ui/assets/alien/buildstat.cfg", &cgs.alienBuildStat ); + // register the inline models cgs.numInlineModels = trap_CM_NumInlineModels( ); diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 322aaa3b..fd8b87d7 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -67,6 +67,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; ASPAWN_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -102,6 +103,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; BARRICADE_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -137,6 +139,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; BOOSTER_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -172,6 +175,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; ACIDTUBE_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -207,6 +211,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; HIVE_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -242,6 +247,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; TRAPPER_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -277,6 +283,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; OVERMIND_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qtrue //qboolean reactorTest; }, { @@ -312,6 +319,7 @@ buildableAttributes_t bg_buildableList[ ] = qtrue, //qboolean creepTest; HOVEL_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qtrue //qboolean reactorTest; }, { @@ -347,6 +355,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -382,6 +391,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -419,6 +429,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -454,6 +465,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qtrue, //qboolean dccTest; + qtrue, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -489,6 +501,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -524,6 +537,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; }, { @@ -559,6 +573,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qtrue //qboolean reactorTest; }, { @@ -594,6 +609,7 @@ buildableAttributes_t bg_buildableList[ ] = qfalse, //qboolean creepTest; 0, //int creepSize; qfalse, //qboolean dccTest; + qfalse, //qboolean transparentTest; qfalse //qboolean reactorTest; } }; @@ -1298,6 +1314,25 @@ static buildableAttributeOverrides_t *BG_FindOverrideForBuildable( int bclass ) return &bg_buildableOverrideList[ bclass ]; } +/* +============== +BG_FindTransparentTestForBuildable +============== +*/ +qboolean BG_FindTransparentTestForBuildable( int bclass ) +{ + int i; + + for( i = 0; i < bg_numBuildables; i++ ) + { + if( bg_buildableList[ i ].buildNum == bclass ) + { + return bg_buildableList[ i ].transparentTest; + } + } + return qfalse; +} + /* ====================== BG_ParseBuildableFile diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 36e01910..877b8b8c 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -1019,6 +1019,7 @@ typedef struct int creepSize; qboolean dccTest; + qboolean transparentTest; qboolean reactorTest; } buildableAttributes_t; @@ -1146,6 +1147,7 @@ int BG_FindCreepTestForBuildable( int bclass ); int BG_FindCreepSizeForBuildable( int bclass ); int BG_FindDCCTestForBuildable( int bclass ); int BG_FindUniqueTestForBuildable( int bclass ); +qboolean BG_FindTransparentTestForBuildable( int bclass ); void BG_InitBuildableOverrides( void ); int BG_FindClassNumForName( char *name ); diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index abe39448..5aba0ece 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -908,6 +908,9 @@ Think function for Alien Barricade */ void ABarricade_Think( gentity_t *self ) { + + self->powered = G_IsOvermindBuilt( ); + //if there is no creep nearby die if( !G_FindCreep( self ) ) { @@ -980,6 +983,8 @@ void AAcidTube_Think( gentity_t *self ) int i, num; gentity_t *enemy; + self->powered = G_IsOvermindBuilt( ); + VectorAdd( self->s.origin, range, maxs ); VectorSubtract( self->s.origin, range, mins ); @@ -1041,6 +1046,8 @@ void AHive_Think( gentity_t *self ) gentity_t *enemy; vec3_t dirToTarget; + self->powered = G_IsOvermindBuilt( ); + self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); VectorAdd( self->s.origin, range, maxs ); @@ -1245,6 +1252,7 @@ Think for alien hovel */ void AHovel_Think( gentity_t *self ) { + self->powered = G_IsOvermindBuilt( ); if( self->spawned ) { if( self->active ) @@ -1517,6 +1525,8 @@ void ATrapper_Think( gentity_t *self ) int range = BG_FindRangeForBuildable( self->s.modelindex ); int firespeed = BG_FindFireSpeedForBuildable( self->s.modelindex ); + self->powered = G_IsOvermindBuilt( ); + G_CreepSlow( self ); self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); @@ -2305,8 +2315,8 @@ void HSpawn_Think( gentity_t *self ) { gentity_t *ent; - //make sure we have power - self->powered = G_FindPower( self ); + // spawns work without power + self->powered = qtrue; if( self->spawned ) { @@ -3218,7 +3228,12 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori if( built->s.generic1 < 0 ) built->s.generic1 = 0; - if( ( built->powered = G_FindPower( built ) ) ) + if( BG_FindTeamForBuildable( built->s.modelindex ) == PTE_ALIENS ) + { + built->powered = qtrue; + built->s.generic1 |= B_POWERED_TOGGLEBIT; + } + else if( ( built->powered = G_FindPower( built ) ) ) built->s.generic1 |= B_POWERED_TOGGLEBIT; if( ( built->dcced = G_FindDCC( built ) ) ) -- cgit