diff options
-rw-r--r-- | src/cgame/cg_buildable.c | 162 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 14 | ||||
-rw-r--r-- | src/game/bg_misc.c | 6 | ||||
-rw-r--r-- | src/game/g_buildable.c | 52 |
4 files changed, 219 insertions, 15 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index 96fa94ce..2414ca12 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -13,14 +13,32 @@ #include "cg_local.h" -//if it ends up this is needed outwith this file i'll make it a bit more tidy -animation_t buildAnimations[ BA_NUM_BUILDABLES ][ MAX_BUILDABLE_ANIMATIONS ]; +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" +}; + +sfxHandle_t defaultAlienSounds[ MAX_BUILDABLE_ANIMATIONS ]; +sfxHandle_t defaultHumanSounds[ MAX_BUILDABLE_ANIMATIONS ]; /* ====================== CG_ParseBuildableAnimationFile -Read a configuration file containing animation coutns and rates +Read a configuration file containing animation counts and rates models/buildables/hivemind/animation.cfg, etc ====================== */ @@ -31,12 +49,11 @@ static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_ int i; char *token; float fps; - int skip; char text[ 20000 ]; fileHandle_t f; animation_t *animations; - animations = buildAnimations[ buildable ]; + animations = cg_buildables[ buildable ].animations; // load the file len = trap_FS_FOpenFile( filename, &f, FS_READ ); @@ -55,10 +72,9 @@ static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_ // parse the text text_p = text; - skip = 0; // quite the compiler warning // read information for each frame - for ( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) + for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) { token = COM_Parse( &text_p ); @@ -100,7 +116,8 @@ static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_ animations[ i ].initialLerp = 1000 / fps; } - if ( i != MAX_BUILDABLE_ANIMATIONS ) { + if( i != MAX_BUILDABLE_ANIMATIONS ) + { CG_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; } @@ -109,6 +126,70 @@ static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_ } /* +====================== +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, *prev; + 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 @@ -117,27 +198,74 @@ Initialises the animation db */ void CG_InitBuildables( ) { - char filename[MAX_QPATH]; + 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 ); + } + 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( "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( "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 ]; + } + } + } } } @@ -158,7 +286,7 @@ static void CG_SetBuildableLerpFrameAnimation( buildable_t buildable, lerpFrame_ if( newAnimation < 0 || newAnimation >= MAX_BUILDABLE_ANIMATIONS ) CG_Error( "Bad animation number: %i", newAnimation ); - anim = &buildAnimations[ buildable ][ newAnimation ]; + anim = &cg_buildables[ buildable ].animations[ newAnimation ]; //this item has just spawned so lf->frameTime will be zero if( !lf->animation ) @@ -182,9 +310,9 @@ cg.time should be between oldFrameTime and frameTime after exit static void CG_RunBuildableLerpFrame( centity_t *cent ) { int f, numFrames; - animation_t *anim; buildable_t buildable = cent->currentState.modelindex; lerpFrame_t *lf = ¢->lerpFrame; + animation_t *anim; buildableAnimNumber_t newAnimation = cent->buildableAnim; // debugging tool to get no animations @@ -196,8 +324,20 @@ static void CG_RunBuildableLerpFrame( centity_t *cent ) // see if the animation sequence is switching if( newAnimation != lf->animationNumber || !lf->animation ) + { CG_SetBuildableLerpFrameAnimation( buildable, lf, newAnimation ); + if( !cg_buildables[ buildable ].sounds[ newAnimation ].looped && + cg_buildables[ buildable ].sounds[ newAnimation ].enabled ) + 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 ) diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index e497fc83..e1aed132 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -429,7 +429,19 @@ typedef struct { typedef struct { - qhandle_t models[MAX_ITEM_MODELS]; + qboolean looped; + qboolean enabled; + + sfxHandle_t sound; +} sound_t; + +typedef struct +{ + qhandle_t models[ MAX_ITEM_MODELS ]; + animation_t animations[ MAX_BUILDABLE_ANIMATIONS ]; + + //same number of sounds as animations + sound_t sounds[ MAX_BUILDABLE_ANIMATIONS ]; } buildableInfo_t; typedef struct { diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 95887e9b..cd54f3d0 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -189,13 +189,13 @@ buildableAttributes_t bg_buildableList[ ] = ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages 1000, //int health; 50, //int damage; - 20, //int splashDamage; - 50, //int splashRadius; + 50, //int splashDamage; + 300, //int splashRadius; MOD_ASPAWN, //int meansOfDeath; BIT_ALIENS, //int team; ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon; BANIM_IDLE1, //int idleAnim; - -1, //int nextthink; + 1000, //int nextthink; 0, //int turretFireSpeed; 0, //int turretRange; WP_NONE, //weapon_t turretProjType; diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 9944f55f..3ae84654 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -454,10 +454,61 @@ void ASpawn_Pain( gentity_t *self, gentity_t *attacker, int damage ) + + //================================================================================== + + +/* +================ +AOvermind_Think + +think function for Alien Acid Tube +================ +*/ +void AOvermind_Think( gentity_t *self ) +{ + int entityList[ MAX_GENTITIES ]; + vec3_t range = { 200, 200, 200 }; + vec3_t mins, maxs; + int i, num; + gentity_t *enemy; + + VectorAdd( self->s.origin, range, maxs ); + VectorSubtract( self->s.origin, range, mins ); + + //do some damage + num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); + for( i = 0; i < num; i++ ) + { + enemy = &g_entities[ entityList[ i ] ]; + + if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) + { + self->timestamp = level.time; + G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage, + self->splashRadius, self, MOD_SHOTGUN, PTE_ALIENS ); + G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); + } + } + + self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); +} + + + + + + +//================================================================================== + + + + + /* ================ ABarricade_Pain @@ -1984,6 +2035,7 @@ gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin case BA_A_HIVEMIND: built->die = ASpawn_Die; + built->think = AOvermind_Think; built->pain = ASpawn_Pain; break; |