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 |