diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/g_buildable.c | 107 | ||||
| -rw-r--r-- | src/game/g_local.h | 1 | ||||
| -rw-r--r-- | src/game/tremulous.h | 2 | 
3 files changed, 110 insertions, 0 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 722bbb5..62d757d 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -944,6 +944,81 @@ void ABarricade_Blast( gentity_t *self )  /*  ================ +ABarricade_Shrink + +Set shrink state for a barricade. When unshrinking, checks to make sure there +is enough room. +================ +*/ +void ABarricade_Shrink( gentity_t *self, qboolean shrink ) +{ +  if ( !self->spawned || self->health <= 0 ) +    shrink = qtrue; +  if ( shrink && self->shrunkTime ) +  { +    int anim; + +    // We need to make sure that the animation has been set to shrunk mode +    // because we start out shrunk but with the construct animation when built +    self->shrunkTime = level.time; +    anim = self->s.torsoAnim & ~( ANIM_FORCEBIT | ANIM_TOGGLEBIT ); +    if ( self->spawned && self->health > 0 && anim != BANIM_DESTROYED ) +    { +      G_SetIdleBuildableAnim( self, BANIM_DESTROYED ); +      G_SetBuildableAnim( self, BANIM_ATTACK1, qtrue ); +    } +    return; +  } + +  if ( !shrink && ( !self->shrunkTime || +       level.time < self->shrunkTime + BARRICADE_SHRINKTIMEOUT ) ) +    return; + +  BG_FindBBoxForBuildable( BA_A_BARRICADE, self->r.mins, self->r.maxs ); + +  if ( shrink ) +  { +    self->r.maxs[ 2 ] = (int)( self->r.maxs[ 2 ] * BARRICADE_SHRINKPROP ); +    self->shrunkTime = level.time; + +    // shrink animation, the destroy animation is used +    if ( self->spawned && self->health > 0 ) +    { +      G_SetBuildableAnim( self, BANIM_ATTACK1, qtrue ); +      G_SetIdleBuildableAnim( self, BANIM_DESTROYED ); +    } +  } +  else +  { +    trace_t tr; +    int anim; + +    trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs, +                self->r.currentOrigin, self->s.number, MASK_PLAYERSOLID ); +    if ( tr.startsolid || tr.fraction < 1.0f ) +    { +      self->r.maxs[ 2 ] = (int)( self->r.maxs[ 2 ] * BARRICADE_SHRINKPROP ); +      return; +    } +    self->shrunkTime = 0; + +    // unshrink animation, IDLE2 has been hijacked for this +    anim = self->s.legsAnim & ~( ANIM_FORCEBIT | ANIM_TOGGLEBIT ); +    if ( self->spawned && self->health > 0 && +         anim != BANIM_CONSTRUCT1 && anim != BANIM_CONSTRUCT2 ) +    { +      G_SetIdleBuildableAnim( self, BG_FindAnimForBuildable( BA_A_BARRICADE ) ); +      G_SetBuildableAnim( self, BANIM_ATTACK2, qtrue ); +    } +  } + +  // a change in size requires a relink +  if ( self->spawned ) +    trap_LinkEntity( self ); +} + +/* +================  ABarricade_Die  Called when an alien spawn dies @@ -977,6 +1052,8 @@ void ABarricade_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker,    self->think = ABarricade_Blast;    self->s.eFlags &= ~EF_FIRING; //prevent any firing effects +  ABarricade_Shrink( self, qtrue ); +    if( self->spawned )      self->nextthink = level.time + 5000;    else @@ -1024,10 +1101,37 @@ void ABarricade_Think( gentity_t *self )    G_CreepSlow( self );    self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); + +  // Shrink if unpowered +  ABarricade_Shrink( self, !self->powered );  } +/* +================ +ABarricade_Touch +Barricades shrink when they are come into contact with an Alien that can +pass through +================ +*/ +void ABarricade_Touch( gentity_t *self, gentity_t *other, trace_t *trace ) +{ +  gclient_t *client = other->client; +  int client_z, min_z; + +  if( !client || client->pers.teamSelection != PTE_ALIENS ) +    return; + +  // Client must be high enough to pass over. Note that STEPSIZE (18) is +  // hardcoded here because we don't include bg_local.h! +  client_z = other->r.currentOrigin[ 2 ] + other->r.mins[ 2 ]; +  min_z = self->r.currentOrigin[ 2 ] - 18 + +          (int)( self->r.maxs[ 2 ] * BARRICADE_SHRINKPROP ); +  if( client_z < min_z ) +    return; +  ABarricade_Shrink( self, qtrue ); +}  //================================================================================== @@ -3599,6 +3703,9 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori        built->die = ABarricade_Die;        built->think = ABarricade_Think;        built->pain = ABarricade_Pain; +      built->touch = ABarricade_Touch; +      built->shrunkTime = 0; +      ABarricade_Shrink( built, qtrue );        break;      case BA_A_BOOSTER: diff --git a/src/game/g_local.h b/src/game/g_local.h index a77a5d6..b5e6e8c 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -217,6 +217,7 @@ struct gentity_s    gentity_t         *overmindNode;      // controlling overmind    qboolean          dcced;              // controlled by a dcc or not?    qboolean          spawned;            // whether or not this buildable has finished spawning +  int               shrunkTime;         // time when a barricade shrunk or zero    int               buildTime;          // when this buildable was built    int               animTime;           // last animation change    int               time1000;           // timer evaluated every second diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 65bd3ca..97738f2 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -239,6 +239,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  #define BARRICADE_SPLASHDAMAGE      50  #define BARRICADE_SPLASHRADIUS      50  #define BARRICADE_CREEPSIZE         120 +#define BARRICADE_SHRINKPROP        0.25f +#define BARRICADE_SHRINKTIMEOUT     500  #define BOOSTER_BP                  12  #define BOOSTER_BT                  15000  | 
