From ab3753cd67f614786efc5bf89db6e317b83a197b Mon Sep 17 00:00:00 2001 From: IronClawTrem Date: Sat, 14 Mar 2020 19:15:57 +0000 Subject: add barricade shrink mechanic --- src/game/g_buildable.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'src/game/g_buildable.c') 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 @@ -942,6 +942,81 @@ void ABarricade_Blast( gentity_t *self ) trap_LinkEntity( self ); //...requires a relink } +/* +================ +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 @@ -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: -- cgit