summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_buildable.c162
-rw-r--r--src/cgame/cg_local.h14
-rw-r--r--src/game/bg_misc.c6
-rw-r--r--src/game/g_buildable.c52
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 = &cent->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;