summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_buildable.c7
-rw-r--r--src/game/g_buildable.c107
-rw-r--r--src/game/g_local.h1
-rw-r--r--src/game/tremulous.h2
4 files changed, 117 insertions, 0 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
index e678ebd..40736e6 100644
--- a/src/cgame/cg_buildable.c
+++ b/src/cgame/cg_buildable.c
@@ -899,6 +899,7 @@ static void CG_BuildableStatusDisplay( centity_t *cent )
qboolean visible = qfalse;
vec3_t mins, maxs;
entityState_t *hit;
+ int anim;
if( BG_FindTeamForBuildable( es->modelindex ) == BIT_ALIENS )
bs = &cgs.alienBuildStat;
@@ -917,6 +918,12 @@ static void CG_BuildableStatusDisplay( centity_t *cent )
// trace for center point
BG_FindBBoxForBuildable( es->modelindex, mins, maxs );
+ // hack for shrunken barricades
+ anim = es->torsoAnim & ~( ANIM_FORCEBIT | ANIM_TOGGLEBIT );
+ if( es->modelindex == BA_A_BARRICADE &&
+ ( anim == BANIM_DESTROYED || !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) )
+ maxs[ 2 ] = (int)( maxs[ 2 ] * BARRICADE_SHRINKPROP );
+
VectorCopy( cent->lerpOrigin, origin );
// center point
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