diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cgame/cg_draw.c | 73 | ||||
| -rw-r--r-- | src/cgame/cg_tutorial.c | 11 | ||||
| -rw-r--r-- | src/cgame/cg_view.c | 12 | ||||
| -rw-r--r-- | src/game/bg_pmove.c | 62 | ||||
| -rw-r--r-- | src/game/bg_public.h | 3 | ||||
| -rw-r--r-- | src/game/g_active.c | 22 | ||||
| -rw-r--r-- | src/game/g_buildable.c | 9 | ||||
| -rw-r--r-- | src/game/g_client.c | 2 | ||||
| -rw-r--r-- | src/game/g_cmds.c | 5 | ||||
| -rw-r--r-- | src/game/tremulous.h | 14 | 
10 files changed, 207 insertions, 6 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 570276b..0af9839 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -375,10 +375,34 @@ static void CG_DrawPlayerStamina( int ownerDraw, rectDef_t *rect,                                    vec4_t backColor, vec4_t foreColor,                                    qhandle_t shader )  { +  playerState_t *ps = &cg.snap->ps; +  float         stamina = ps->stats[ STAT_STAMINA ]; +  float         maxStaminaBy3 = (float)STAMINA_MAX / 3.0f;    float         progress;    vec4_t        color; -  progress = 0.0f; +  switch( ownerDraw ) +  { +    case CG_PLAYER_STAMINA_1: +      progress = ( stamina - 2 * (int)maxStaminaBy3 ) / maxStaminaBy3; +      break; +    case CG_PLAYER_STAMINA_2: +      progress = ( stamina - (int)maxStaminaBy3 ) / maxStaminaBy3; +      break; +    case CG_PLAYER_STAMINA_3: +  progress = stamina / maxStaminaBy3; +      break; +    case CG_PLAYER_STAMINA_4: +      progress = ( stamina + STAMINA_MAX ) / STAMINA_MAX; +      break; +    default: +      return; +  } + +  if( progress > 1.0f ) +    progress  = 1.0f; +  else if( progress < 0.0f ) +    progress = 0.0f;    Vector4Lerp( progress, backColor, foreColor, color ); @@ -395,9 +419,25 @@ CG_DrawPlayerStaminaBolt  static void CG_DrawPlayerStaminaBolt( rectDef_t *rect, vec4_t backColor,                                        vec4_t foreColor, qhandle_t shader )  { +  float         stamina = cg.snap->ps.stats[ STAT_STAMINA ];    vec4_t        color; -  Vector4Copy( backColor, color ); +  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_SPEEDBOOST ) +  { +    if( stamina >= 0 ) +      Vector4Lerp( ( sin( cg.time / 150.0f ) + 1 ) / 2, +                   backColor, foreColor, color ); +    else +      Vector4Lerp( ( sin( cg.time / 2000.0f ) + 1 ) / 2, +                   backColor, foreColor, color ); +  } +  else +  { +    if( stamina < 0 ) +      Vector4Copy( backColor, color ); +    else +      Vector4Copy( foreColor, color ); +  }    trap_R_SetColor( color );    CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); @@ -3420,6 +3460,31 @@ void CG_RunMenuScript( char **args )  }  //END TA UI + +/* +================ +CG_DrawLighting + +================ +*/ +static void CG_DrawLighting( void ) +{ +  // centity_t   *cent; + +  // cent = &cg_entities[ cg.snap->ps.clientNum ]; + +  //fade to black if stamina is low +  if( ( cg.snap->ps.stats[ STAT_STAMINA ] < STAMINA_BLACKOUT_LEVEL ) && +      ( cg.snap->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) ) +  { +    vec4_t black = { 0, 0, 0, 0 }; +    black[ 3 ] = 1.0 - ( (float)( cg.snap->ps.stats[ STAT_STAMINA ] + 1000 ) / 200.0f ); +    trap_R_SetColor( black ); +    CG_DrawPic( 0, 0, 640, 480, cgs.media.whiteShader ); +    trap_R_SetColor( NULL ); +  } +} +  /*  =============================================================================== @@ -4097,6 +4162,10 @@ static void CG_Draw2D( void )    if( cg.levelShot )      return; +  // fading to black if stamina runs out +  // (only 2D that can't be disabled) +  CG_DrawLighting( ); +    if( cg_draw2D.integer == 0 )      return; diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c index d2f01b3..d36ecac 100644 --- a/src/cgame/cg_tutorial.c +++ b/src/cgame/cg_tutorial.c @@ -514,6 +514,17 @@ static void CG_HumanText( char *text, playerState_t *ps )            BG_Upgrade( UP_MEDKIT )->humanName ) );    } +  if( ps->stats[ STAT_STAMINA ] <= STAMINA_BLACKOUT_LEVEL ) +  { +    Q_strcat( text, MAX_TUTORIAL_TEXT, +        "You are blacking out. Stop sprinting to recover stamina\n" ); +  } +  else if( ps->stats[ STAT_STAMINA ] <= STAMINA_SLOW_LEVEL ) +  { +    Q_strcat( text, MAX_TUTORIAL_TEXT, +        "Your stamina is low. Stop sprinting to recover\n" ); +  } +    switch( cg.nearUsableBuildable )    {      case BA_H_ARMOURY: diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index 333e421..1221fe9 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -809,6 +809,18 @@ void CG_OffsetFirstPersonView( void )          cg.predictedPlayerState.pm_type == PM_JETPACK ) )    {      angles[PITCH] += cg.bobfracsin * bob2 * 0.5; + +    // heavy breathing effects //FIXME: sound +    if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < STAMINA_BREATHING_LEVEL ) +    { +      float deltaBreath = ( cg.predictedPlayerState.stats[ STAT_STAMINA ] - +                            STAMINA_BREATHING_LEVEL ) / -250.0; +      float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath; + +      deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5; + +      angles[ PITCH ] -= deltaAngle; +    }    }  //=================================== diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index 63b67fa..ecdaccf 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -406,6 +406,57 @@ static float PM_CmdScale( usercmd_t *cmd )    if( pm->ps->stats[ STAT_TEAM ] == TEAM_HUMANS && pm->ps->pm_type == PM_NORMAL )    { +    qboolean wasSprinting; +    qboolean sprint; +    wasSprinting = sprint = pm->ps->stats[ STAT_STATE ] & SS_SPEEDBOOST; + +    if( pm->ps->persistant[ PERS_STATE ] & PS_SPRINTTOGGLE ) +    { +      if( cmd->buttons & BUTTON_SPRINT && +          !( pm->ps->pm_flags & PMF_SPRINTHELD ) ) +      { +        sprint = !sprint; +        pm->ps->pm_flags |= PMF_SPRINTHELD; +      } +      else if( pm->ps->pm_flags & PMF_SPRINTHELD && +               !( cmd->buttons & BUTTON_SPRINT ) ) +        pm->ps->pm_flags &= ~PMF_SPRINTHELD; +    } +    else +      sprint = cmd->buttons & BUTTON_SPRINT; + +    if( sprint ) +      pm->ps->stats[ STAT_STATE ] |= SS_SPEEDBOOST;       +    else if( wasSprinting && !sprint ) +      pm->ps->stats[ STAT_STATE ] &= ~SS_SPEEDBOOST; + +    // Walk overrides sprint. We keep the state that we want to be sprinting +    //  (above), but don't apply the modifier, and in g_active we skip taking +    //  the stamina too. +    if( sprint && !( cmd->buttons & BUTTON_WALKING ) ) +      modifier *= HUMAN_SPRINT_MODIFIER; +    else +      modifier *= HUMAN_JOG_MODIFIER; + +    if( cmd->forwardmove < 0 ) +    { +      //can't run backwards +      modifier *= HUMAN_BACK_MODIFIER; +    } +    else if( cmd->rightmove ) +    { +      //can't move that fast sideways +      modifier *= HUMAN_SIDE_MODIFIER; +    } + +    //must have have stamina to jump +    if( pm->ps->stats[ STAT_STAMINA ] < STAMINA_SLOW_LEVEL + STAMINA_JUMP_TAKE ) +      cmd->upmove = 0; + +    //slow down once stamina depletes +    if( pm->ps->stats[ STAT_STAMINA ] <= STAMINA_SLOW_LEVEL ) +      modifier *= (float)( pm->ps->stats[ STAT_STAMINA ] + STAMINA_MAX ) / (float)(STAMINA_SLOW_LEVEL + STAMINA_MAX); +      if( pm->ps->stats[ STAT_STATE ] & SS_CREEPSLOWED )      {        if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, pm->ps->stats ) || @@ -906,6 +957,10 @@ static qboolean PM_CheckJump( void )        pm->ps->stats[ STAT_MISC ] > 0 )      return qfalse; +  if( ( pm->ps->stats[ STAT_TEAM ] == TEAM_HUMANS ) && +      ( pm->ps->stats[ STAT_STAMINA ] < STAMINA_SLOW_LEVEL + STAMINA_JUMP_TAKE ) ) +    return qfalse; +    //no bunny hopping off a dodge    if( pm->ps->stats[ STAT_TEAM ] == TEAM_HUMANS &&         pm->ps->pm_time ) @@ -944,6 +999,10 @@ static qboolean PM_CheckJump( void )    pml.walking = qfalse;    pm->ps->pm_flags |= PMF_JUMP_HELD; +  // take some stamina off +  if( pm->ps->stats[ STAT_TEAM ] == TEAM_HUMANS ) +    pm->ps->stats[ STAT_STAMINA ] -= STAMINA_JUMP_TAKE; +    pm->ps->groundEntityNum = ENTITYNUM_NONE;    // jump away from wall @@ -2748,6 +2807,9 @@ static void PM_Footsteps( void )    bobmove *= BG_Class( pm->ps->stats[ STAT_CLASS ] )->bobCycle; +  if( pm->ps->stats[ STAT_STATE ] & SS_SPEEDBOOST ) +    bobmove *= HUMAN_SPRINT_MODIFIER; +    // check for footstep / splash sounds    old = pm->ps->bobCycle;    pm->ps->bobCycle = (int)( old + bobmove * pml.msec ) & 255; diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 61da2f7..1e9d23c 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -224,12 +224,13 @@ typedef enum    STAT_MAX_HEALTH,// health / armor limit, changable by handicap    STAT_CLASS,     // player class (for aliens AND humans)    STAT_TEAM,      // player team +  STAT_STAMINA,   // stamina (human only)    STAT_STATE,     // client states e.g. wall climbing    STAT_MISC,      // for uh...misc stuff (pounce, trample, lcannon)    STAT_BUILDABLE, // which ghost model to display for building    STAT_FALLDIST,  // the distance the player fell    STAT_VIEWLOCK   // direction to lock the view in -  // netcode has space for 4 more +  // netcode has space for 3 more  } statIndex_t;  #define SCA_WALLCLIMBER         0x00000001 diff --git a/src/game/g_active.c b/src/game/g_active.c index 2bf6400..0c84f57 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -631,6 +631,7 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )        client->ps.pm_flags |= PMF_QUEUED;      client->ps.speed = client->pers.flySpeed; +    client->ps.stats[ STAT_STAMINA ] = 0;      client->ps.stats[ STAT_MISC ] = 0;      client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;      client->ps.stats[ STAT_CLASS ] = PCL_NONE; @@ -806,10 +807,26 @@ void ClientTimerActions( gentity_t *ent, int msec )  	  client->ps.stats[ STAT_STATE ] &= ~SS_INVI;      } -    // Regenerate health if we have got a Biokit +    // Restore or subtract stamina +    if( stopped || client->ps.pm_type == PM_JETPACK ) +      client->ps.stats[ STAT_STAMINA ] += STAMINA_STOP_RESTORE; +    else if( ( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST ) && +             !( client->buttons & BUTTON_WALKING ) ) // walk overrides sprint +      client->ps.stats[ STAT_STAMINA ] -= STAMINA_SPRINT_TAKE; +    else if( walking || crouched ) +      client->ps.stats[ STAT_STAMINA ] += STAMINA_WALK_RESTORE; +       +    // Check stamina limits +    if( client->ps.stats[ STAT_STAMINA ] > STAMINA_MAX ) +      client->ps.stats[ STAT_STAMINA ] = STAMINA_MAX; +    else if( client->ps.stats[ STAT_STAMINA ] < -STAMINA_MAX ) +      client->ps.stats[ STAT_STAMINA ] = -STAMINA_MAX; + +    // Regenerate health and stamina if we have got a Biokit      if( BG_InventoryContainsUpgrade( UP_BIOKIT, client->ps.stats ) )      {        int rate_health  = BIOKIT_HEALTH_RATE; +      int rate_stamina = BIOKIT_STAMINA_RATE;        if( ent->nextRegenTime < level.time && ent->health > 0 && rate_health > 0 &&             ent->health < client->ps.stats[ STAT_MAX_HEALTH ] ) @@ -823,6 +840,9 @@ void ClientTimerActions( gentity_t *ent, int msec )          ent->nextRegenTime = level.time + 5000/rate_health;          ent->client->alreadyRegenerated = qtrue;        } + +      if( client->ps.stats[ STAT_STAMINA ] + rate_stamina <= STAMINA_MAX ) +        client->ps.stats[ STAT_STAMINA ] += rate_stamina;      }      if( weapon == WP_ABUILD || diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index fa66979..21f5424 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -2830,7 +2830,8 @@ void HMedistat_Think( gentity_t *self )          if( player->client && player->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS )          { -          if( player->health < player->client->ps.stats[ STAT_MAX_HEALTH ] && +          if( ( player->health < player->client->ps.stats[ STAT_MAX_HEALTH ] || +                player->client->ps.stats[ STAT_STAMINA ] < STAMINA_MAX ) &&                PM_Live( player->client->ps.pm_type ) )            {              self->enemy = player; @@ -2860,6 +2861,12 @@ void HMedistat_Think( gentity_t *self )      }      else if( self->enemy && self->enemy->client ) //heal!      { +      if( self->enemy->client->ps.stats[ STAT_STAMINA ] <  STAMINA_MAX ) +        self->enemy->client->ps.stats[ STAT_STAMINA ] += STAMINA_MEDISTAT_RESTORE; + +      if( self->enemy->client->ps.stats[ STAT_STAMINA ] > STAMINA_MAX ) +        self->enemy->client->ps.stats[ STAT_STAMINA ] = STAMINA_MAX; +        self->enemy->health++;        //if they're completely healed, give them a medkit diff --git a/src/game/g_client.c b/src/game/g_client.c index bfb79b9..896a7fc 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1505,6 +1505,8 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles    for( i = 0; i < MAX_CLIENTS; i++ )      ent->credits[ i ] = 0; +  client->ps.stats[ STAT_STAMINA ] = STAMINA_MAX; +    G_SetOrigin( ent, spawn_origin );    VectorCopy( spawn_origin, client->ps.origin ); diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 74dea71..f3cada7 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -450,7 +450,7 @@ void Cmd_Give_f( gentity_t *ent )    if( trap_Argc( ) < 2 )    {      ADMP( "usage: give [what]\n" ); -    ADMP( "usage: valid choices are: all, health, funds [amount], " +    ADMP( "usage: valid choices are: all, health, funds [amount], stamina, "            "poison, gas, ammo\n" );      return;    } @@ -487,6 +487,9 @@ void Cmd_Give_f( gentity_t *ent )      G_AddCreditToClient( ent->client, (short)credits, qtrue );    } +  if( give_all || Q_stricmp( name, "stamina" ) == 0 ) +    ent->client->ps.stats[ STAT_STAMINA ] = STAMINA_MAX; +    if( Q_stricmp( name, "poison" ) == 0 )    {      if( ent->client->pers.teamSelection == TEAM_HUMANS ) diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 3db55f9..229e4ea 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -324,7 +324,21 @@ TREMULOUS EDGE MOD SRC FILE   * HUMAN   */ +#define HUMAN_SPRINT_MODIFIER       1.28f +#define HUMAN_JOG_MODIFIER          1.1f +#define HUMAN_BACK_MODIFIER         0.8f +#define HUMAN_SIDE_MODIFIER         0.9f  #define HUMAN_LAND_FRICTION         3.0f +#define STAMINA_STOP_RESTORE        20 +#define STAMINA_WALK_RESTORE        15 +#define STAMINA_MEDISTAT_RESTORE    30 +#define STAMINA_SPRINT_TAKE         8 +#define STAMINA_JUMP_TAKE           250 +#define STAMINA_DODGE_TAKE          250 +#define STAMINA_MAX                 1200 +#define STAMINA_BREATHING_LEVEL     0 +#define STAMINA_SLOW_LEVEL          -500 +#define STAMINA_BLACKOUT_LEVEL      -800  #define HUMAN_SPAWN_REPEAT_TIME     11000  #define HUMAN_REGEN_DAMAGE_TIME     2000 		//msec since damage before dcc repairs  #define HUMAN_MAX_CREDITS           2000  | 
