diff options
author | Tim Angus <tim@ngus.net> | 2009-10-03 11:37:35 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:15:11 +0000 |
commit | bac576514472b4f1d70a53078182d29e93c34d59 (patch) | |
tree | acb6f0056003701d26d9d1ed3fb48bb195187be3 | |
parent | bcc79996c4c254a528e7b00f260d8ebd09e2a820 (diff) |
* First person weapon animation
-rw-r--r-- | src/cgame/cg_animation.c | 4 | ||||
-rw-r--r-- | src/cgame/cg_animmapobj.c | 4 | ||||
-rw-r--r-- | src/cgame/cg_buildable.c | 78 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 7 | ||||
-rw-r--r-- | src/cgame/cg_particles.c | 2 | ||||
-rw-r--r-- | src/cgame/cg_players.c | 81 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 164 | ||||
-rw-r--r-- | src/game/bg_misc.c | 29 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 74 | ||||
-rw-r--r-- | src/game/bg_public.h | 26 | ||||
-rw-r--r-- | src/qcommon/msg.c | 2 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 3 |
12 files changed, 278 insertions, 196 deletions
diff --git a/src/cgame/cg_animation.c b/src/cgame/cg_animation.c index c370c534..693cf6a7 100644 --- a/src/cgame/cg_animation.c +++ b/src/cgame/cg_animation.c @@ -31,7 +31,7 @@ Sets cg.snap, cg.oldFrame, and cg.backlerp cg.time should be between oldFrameTime and frameTime after exit =============== */ -void CG_RunLerpFrame( lerpFrame_t *lf ) +void CG_RunLerpFrame( lerpFrame_t *lf, float scale ) { int f, numFrames; animation_t *anim; @@ -61,7 +61,9 @@ void CG_RunLerpFrame( lerpFrame_t *lf ) lf->frameTime = lf->oldFrameTime + anim->frameLerp; f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; + f *= scale; numFrames = anim->numFrames; + if( anim->flipflop ) numFrames *= 2; diff --git a/src/cgame/cg_animmapobj.c b/src/cgame/cg_animmapobj.c index 12253149..ae2309dd 100644 --- a/src/cgame/cg_animmapobj.c +++ b/src/cgame/cg_animmapobj.c @@ -31,7 +31,7 @@ CG_DoorAnimation */ static void CG_DoorAnimation( centity_t *cent, int *old, int *now, float *backLerp ) { - CG_RunLerpFrame( ¢->lerpFrame ); + CG_RunLerpFrame( ¢->lerpFrame, 1.0f ); *old = cent->lerpFrame.oldFrame; *now = cent->lerpFrame.frame; @@ -117,7 +117,7 @@ static void CG_AMOAnimation( centity_t *cent, int *old, int *now, float *backLer cent->lerpFrame.frameTime += delta; } - CG_RunLerpFrame( ¢->lerpFrame ); + CG_RunLerpFrame( ¢->lerpFrame, 1.0f ); cent->miscTime = cg.time; } diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index 45f1e8dd..7b20b8b8 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -427,19 +427,10 @@ 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 ) { @@ -466,72 +457,11 @@ static void CG_RunBuildableLerpFrame( centity_t *cent ) 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; + CG_RunLerpFrame( lf, 1.0f ); - 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 ); + // animation ended + if( lf->frameTime == cg.time ) + cent->buildableAnim = cent->currentState.torsoAnim; } /* diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 4b375d43..470069c1 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -569,7 +569,7 @@ typedef struct typedef struct { - lerpFrame_t legs, torso, flag, nonseg; + lerpFrame_t legs, torso, nonseg, weapon; int painTime; int painDirection; // flip from 0 to 1 @@ -825,6 +825,9 @@ typedef struct weaponInfo_s qhandle_t barrelModel; qhandle_t flashModel; + animation_t animations[ MAX_WEAPON_ANIMATIONS ]; + qboolean noDrift; + vec3_t weaponMidpoint; // so it will rotate centered instead of by tag qhandle_t weaponIcon; @@ -1669,7 +1672,7 @@ void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir ); // // cg_animation.c // -void CG_RunLerpFrame( lerpFrame_t *lf ); +void CG_RunLerpFrame( lerpFrame_t *lf, float scale ); // // cg_animmapobj.c diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c index 195c5ff3..c7023dbf 100644 --- a/src/cgame/cg_particles.c +++ b/src/cgame/cg_particles.c @@ -2416,7 +2416,7 @@ static void CG_RenderParticle( particle_t *p ) p->lf.animation = &bp->modelAnimation; //run animation - CG_RunLerpFrame( &p->lf ); + CG_RunLerpFrame( &p->lf, 1.0f ); re.oldframe = p->lf.oldFrame; re.frame = p->lf.frame; diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c index 78cbe8d8..f729164a 100644 --- a/src/cgame/cg_players.c +++ b/src/cgame/cg_players.c @@ -841,90 +841,11 @@ cg.time should be between oldFrameTime and frameTime after exit */ static void CG_RunPlayerLerpFrame( clientInfo_t *ci, lerpFrame_t *lf, int newAnimation, float speedScale ) { - int f, numFrames; - animation_t *anim; - - // 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 ) - { CG_SetLerpFrameAnimation( ci, lf, newAnimation ); - } - // 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; - f *= speedScale; // adjust for haste, etc - 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; - } - } - - 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_RunLerpFrame( lf, speedScale ); } diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c index e3776779..f9ea2985 100644 --- a/src/cgame/cg_weapons.c +++ b/src/cgame/cg_weapons.c @@ -80,6 +80,104 @@ void CG_InitUpgrades( void ) /* +====================== +CG_ParseWeaponAnimationFile + +Read a configuration file containing animation counts and rates +models/weapons/rifle/animation.cfg, etc +====================== +*/ +static qboolean CG_ParseWeaponAnimationFile( const char *filename, weaponInfo_t *weapon ) +{ + char *text_p; + int len; + int i; + char *token; + float fps; + char text[ 20000 ]; + fileHandle_t f; + animation_t *animations; + + animations = weapon->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 = WANIM_NONE + 1; i < MAX_WEAPON_ANIMATIONS; i++ ) + { + + token = COM_Parse( &text_p ); + if( !*token ) + break; + + if( !Q_stricmp( token, "noDrift" ) ) + { + weapon->noDrift = qtrue; + continue; + } + + 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_WEAPON_ANIMATIONS ) + { + CG_Printf( "Error parsing animation file: %s\n", filename ); + return qfalse; + } + + return qtrue; +} + + +/* =============== CG_ParseWeaponModeSection @@ -627,6 +725,11 @@ void CG_RegisterWeapon( int weaponNum ) if( !CG_ParseWeaponFile( path, weaponInfo ) ) Com_Printf( S_COLOR_RED "ERROR: failed to parse %s\n", path ); + Com_sprintf( path, MAX_QPATH, "models/weapons/%s/animation.cfg", BG_FindNameForWeapon( weaponNum ) ); + + if( !CG_ParseWeaponAnimationFile( path, weaponInfo ) ) + Com_Printf( S_COLOR_RED "ERROR: failed to parse %s\n", path ); + // calc midpoint for rotation trap_R_ModelBounds( weaponInfo->weaponModel, mins, maxs ); for( i = 0 ; i < 3 ; i++ ) @@ -666,6 +769,53 @@ VIEW WEAPON */ /* +=============== +CG_SetWeaponLerpFrameAnimation + +may include ANIM_TOGGLEBIT +=============== +*/ +static void CG_SetWeaponLerpFrameAnimation( weapon_t weapon, lerpFrame_t *lf, int newAnimation ) +{ + animation_t *anim; + + lf->animationNumber = newAnimation; + newAnimation &= ~ANIM_TOGGLEBIT; + + if( newAnimation < 0 || newAnimation >= MAX_WEAPON_ANIMATIONS ) + CG_Error( "Bad animation number: %i", newAnimation ); + + anim = &cg_weapons[ weapon ].animations[ newAnimation ]; + + lf->animation = anim; + lf->animationTime = lf->frameTime + anim->initialLerp; + + if( cg_debugAnim.integer ) + CG_Printf( "Anim: %i\n", newAnimation ); +} + +/* +=============== +CG_WeaponAnimation +=============== +*/ +static void CG_WeaponAnimation( centity_t *cent, int *old, int *now, float *backLerp ) +{ + lerpFrame_t *lf = ¢->pe.weapon; + entityState_t *es = ¢->currentState; + + // see if the animation sequence is switching + if( es->weaponAnim != lf->animationNumber || !lf->animation ) + CG_SetWeaponLerpFrameAnimation( es->weapon, lf, es->weaponAnim ); + + CG_RunLerpFrame( lf, 1.0f ); + + *old = lf->oldFrame; + *now = lf->frame; + *backLerp = lf->backlerp; +} + +/* ================= CG_MapTorsoToWeaponFrame @@ -700,10 +850,13 @@ CG_CalculateWeaponPosition */ static void CG_CalculateWeaponPosition( vec3_t origin, vec3_t angles ) { - float scale; - int delta; - float fracsin; - float bob; + float scale; + int delta; + float fracsin; + float bob; + weaponInfo_t *weapon; + + weapon = &cg_weapons[ cg.predictedPlayerState.weapon ]; VectorCopy( cg.refdef.vieworg, origin ); VectorCopy( cg.refdefViewAngles, angles ); @@ -726,7 +879,7 @@ static void CG_CalculateWeaponPosition( vec3_t origin, vec3_t angles ) } // drop the weapon when landing - if( !BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_NOWEAPONDRIFT ) ) + if( weapon->noDrift ) { delta = cg.time - cg.landTime; if( delta < LAND_DEFLECT_TIME ) @@ -880,6 +1033,7 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent if( !noGunModel ) { + CG_WeaponAnimation( cent, &gun.oldframe, &gun.frame, &gun.backlerp ); CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" ); trap_R_AddRefEntityToScene( &gun ); diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 275f5b41..64924aaa 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -1735,8 +1735,7 @@ classAttributes_t bg_classList[ ] = LEVEL0_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL0_REGEN, //int regenRate; - SCA_WALLCLIMBER|SCA_NOWEAPONDRIFT| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_WALLCLIMBER|SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL0, //weapon_t startWeapon 0.0f, //float buildDist; 140, //int fov; @@ -1778,8 +1777,7 @@ classAttributes_t bg_classList[ ] = LEVEL1_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL1_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT| - SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; + SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; WP_ALEVEL1, //weapon_t startWeapon 0.0f, //float buildDist; 120, //int fov; @@ -1821,8 +1819,7 @@ classAttributes_t bg_classList[ ] = LEVEL1_UPG_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL1_UPG_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT|SCA_FOVWARPS| - SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; + SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; WP_ALEVEL1_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 120, //int fov; @@ -1862,8 +1859,7 @@ classAttributes_t bg_classList[ ] = LEVEL2_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL2_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_WALLJUMPER|SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL2, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; @@ -1903,8 +1899,7 @@ classAttributes_t bg_classList[ ] = LEVEL2_UPG_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL2_UPG_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_WALLJUMPER|SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL2_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; @@ -1945,8 +1940,7 @@ classAttributes_t bg_classList[ ] = LEVEL3_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL3_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL3, //weapon_t startWeapon 0.0f, //float buildDist; 110, //int fov; @@ -1987,8 +1981,7 @@ classAttributes_t bg_classList[ ] = LEVEL3_UPG_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL3_UPG_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL3_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 110, //int fov; @@ -2030,8 +2023,7 @@ classAttributes_t bg_classList[ ] = LEVEL4_HEALTH, //int health; 0.0f, //float fallDamage; LEVEL4_REGEN, //int regenRate; - SCA_NOWEAPONDRIFT| - SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; + SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; WP_ALEVEL4, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; @@ -2070,8 +2062,7 @@ classAttributes_t bg_classList[ ] = 100, //int health; 1.0f, //float fallDamage; 0, //int regenRate; - SCA_TAKESFALLDAMAGE| - SCA_CANUSELADDERS, //int abilities; + SCA_TAKESFALLDAMAGE|SCA_CANUSELADDERS, //int abilities; WP_NONE, //special-cased in g_client.c //weapon_t startWeapon 110.0f, //float buildDist; 90, //int fov; @@ -4953,6 +4944,7 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean s->time2 = ps->movementDir; s->legsAnim = ps->legsAnim; s->torsoAnim = ps->torsoAnim; + s->weaponAnim = ps->weaponAnim; s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number // so corpses can also reference the proper config s->eFlags = ps->eFlags; @@ -5062,6 +5054,7 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s s->time2 = ps->movementDir; s->legsAnim = ps->legsAnim; s->torsoAnim = ps->torsoAnim; + s->weaponAnim = ps->weaponAnim; s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number // so corpses can also reference the proper config s->eFlags = ps->eFlags; diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index d0f0a1c6..5179c24c 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -103,6 +103,20 @@ void PM_StartTorsoAnim( int anim ) /* =================== +PM_StartWeaponAnim +=================== +*/ +static void PM_StartWeaponAnim( int anim ) +{ + if( pm->ps->pm_type >= PM_DEAD ) + return; + + pm->ps->weaponAnim = ( ( pm->ps->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) + | anim; +} + +/* +=================== PM_StartLegsAnim =================== */ @@ -170,6 +184,19 @@ static void PM_ContinueTorsoAnim( int anim ) /* =================== +PM_ContinueWeaponAnim +=================== +*/ +static void PM_ContinueWeaponAnim( int anim ) +{ + if( ( pm->ps->weaponAnim & ~ANIM_TOGGLEBIT ) == anim ) + return; + + PM_StartWeaponAnim( anim ); +} + +/* +=================== PM_ForceLegsAnim =================== */ @@ -2716,7 +2743,10 @@ static void PM_BeginWeaponChange( int weapon ) pm->ps->stats[ STAT_BUILDABLE ] = BA_NONE; if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) + { PM_StartTorsoAnim( TORSO_DROP ); + PM_StartWeaponAnim( WANIM_DROP ); + } } @@ -2741,7 +2771,10 @@ static void PM_FinishWeaponChange( void ) pm->ps->weaponTime += 250; if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) + { PM_StartTorsoAnim( TORSO_RAISE ); + PM_StartWeaponAnim( WANIM_RAISE ); + } } @@ -2753,15 +2786,17 @@ PM_TorsoAnimation */ static void PM_TorsoAnimation( void ) { - if( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) - return; - if( pm->ps->weaponstate == WEAPON_READY ) { - if( pm->ps->weapon == WP_BLASTER ) - PM_ContinueTorsoAnim( TORSO_STAND2 ); - else - PM_ContinueTorsoAnim( TORSO_STAND ); + if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) ) + { + if( pm->ps->weapon == WP_BLASTER ) + PM_ContinueTorsoAnim( TORSO_STAND2 ); + else + PM_ContinueTorsoAnim( TORSO_STAND ); + } + + PM_ContinueWeaponAnim( WANIM_IDLE ); } } @@ -2969,6 +3004,8 @@ static void PM_Weapon( void ) PM_ContinueTorsoAnim( TORSO_STAND ); } + PM_ContinueWeaponAnim( WANIM_IDLE ); + return; } @@ -3010,7 +3047,6 @@ static void PM_Weapon( void ) //allow some time for the weapon to be raised pm->ps->weaponstate = WEAPON_RAISING; - PM_StartTorsoAnim( TORSO_RAISE ); pm->ps->weaponTime += 250; return; } @@ -3023,6 +3059,7 @@ static void PM_Weapon( void ) //drop the weapon PM_StartTorsoAnim( TORSO_DROP ); + PM_StartWeaponAnim( WANIM_RELOAD ); pm->ps->weaponTime += BG_FindReloadTimeForWeapon( pm->ps->weapon ); return; @@ -3207,15 +3244,18 @@ static void PM_Weapon( void ) if( pm->ps->weaponstate == WEAPON_READY ) { PM_StartTorsoAnim( TORSO_ATTACK ); + PM_StartWeaponAnim( WANIM_ATTACK1 ); } break; case WP_BLASTER: PM_StartTorsoAnim( TORSO_ATTACK2 ); + PM_StartWeaponAnim( WANIM_ATTACK1 ); break; default: PM_StartTorsoAnim( TORSO_ATTACK ); + PM_StartWeaponAnim( WANIM_ATTACK1 ); break; } } @@ -3227,20 +3267,38 @@ static void PM_Weapon( void ) int num = abs( pm->ps->commandTime ) % 3; if( num == 0 ) + { PM_ForceLegsAnim( NSPA_ATTACK1 ); + PM_StartWeaponAnim( WANIM_ATTACK1 ); + } else if( num == 1 ) + { PM_ForceLegsAnim( NSPA_ATTACK2 ); + PM_StartWeaponAnim( WANIM_ATTACK2 ); + } else if( num == 2 ) + { PM_ForceLegsAnim( NSPA_ATTACK3 ); + PM_StartWeaponAnim( WANIM_ATTACK3 ); + } } else { if( attack1 ) + { PM_ForceLegsAnim( NSPA_ATTACK1 ); + PM_StartWeaponAnim( WANIM_ATTACK1 ); + } else if( attack2 ) + { PM_ForceLegsAnim( NSPA_ATTACK2 ); + PM_StartWeaponAnim( WANIM_ATTACK2 ); + } else if( attack3 ) + { PM_ForceLegsAnim( NSPA_ATTACK3 ); + PM_StartWeaponAnim( WANIM_ATTACK3 ); + } } pm->ps->torsoTimer = TIMER_ATTACK; diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 1ee8d36a..361d857a 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -225,11 +225,10 @@ typedef enum #define SCA_WALLCLIMBER 0x00000001 #define SCA_TAKESFALLDAMAGE 0x00000002 #define SCA_CANZOOM 0x00000004 -#define SCA_NOWEAPONDRIFT 0x00000008 -#define SCA_FOVWARPS 0x00000010 -#define SCA_ALIENSENSE 0x00000020 -#define SCA_CANUSELADDERS 0x00000040 -#define SCA_WALLJUMPER 0x00000080 +#define SCA_FOVWARPS 0x00000008 +#define SCA_ALIENSENSE 0x00000010 +#define SCA_CANUSELADDERS 0x00000020 +#define SCA_WALLJUMPER 0x00000040 #define SS_WALLCLIMBING 0x00000001 #define SS_WALLCLIMBINGCEILING 0x00000002 @@ -770,6 +769,23 @@ typedef enum MAX_BUILDABLE_ANIMATIONS } buildableAnimNumber_t; +typedef enum +{ + WANIM_NONE, + + WANIM_IDLE, + + WANIM_DROP, + WANIM_RELOAD, + WANIM_RAISE, + + WANIM_ATTACK1, + WANIM_ATTACK2, + WANIM_ATTACK3, + + MAX_WEAPON_ANIMATIONS +} weaponAnimNumber_t; + typedef struct animation_s { int firstFrame; diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c index ac581b9e..47fbc2dc 100644 --- a/src/qcommon/msg.c +++ b/src/qcommon/msg.c @@ -808,6 +808,7 @@ netField_t entityStateFields[] = { NETF(angles2[1]), 0 }, { NETF(eType), 8 }, { NETF(torsoAnim), 8 }, +{ NETF(weaponAnim), 8 }, { NETF(eventParm), 8 }, { NETF(legsAnim), 8 }, { NETF(groundEntityNum), GENTITYNUM_BITS }, @@ -1125,6 +1126,7 @@ netField_t playerStateFields[] = { PSF(pm_time), -16 }, { PSF(eventSequence), 16 }, { PSF(torsoAnim), 8 }, +{ PSF(weaponAnim), 8 }, { PSF(movementDir), 4 }, { PSF(events[0]), 8 }, { PSF(legsAnim), 8 }, diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index 667fba73..232982f5 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -1060,6 +1060,8 @@ typedef struct playerState_s { int torsoTimer; // don't change low priority animations until this runs out int torsoAnim; // mask off ANIM_TOGGLEBIT + int weaponAnim; // mask off ANIM_TOGGLEBIT + int movementDir; // a number 0 to 7 that represents the reletive angle // of movement to the view angle (axial and diagonals) // when at rest, the value will remain unchanged @@ -1212,6 +1214,7 @@ typedef struct entityState_s { int weapon; // determines weapon and flash model, etc int legsAnim; // mask off ANIM_TOGGLEBIT int torsoAnim; // mask off ANIM_TOGGLEBIT + int weaponAnim; // mask off ANIM_TOGGLEBIT int generic1; } entityState_t; |