summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/g_buildable.c358
-rw-r--r--src/game/tremulous.h8
2 files changed, 126 insertions, 240 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 7ef5054e..7a8cd126 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -400,15 +400,17 @@ qboolean G_FindCreep( gentity_t *self )
return qtrue;
//if self does not have a parentNode or it's parentNode is invalid find a new one
- if( self->client || ( self->parentNode == NULL ) || !self->parentNode->inuse )
+ if( self->client || self->parentNode == NULL || !self->parentNode->inuse ||
+ self->parentNode->health <= 0 )
{
for ( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ )
{
if( ent->s.eType != ET_BUILDABLE )
continue;
- if( ( ent->s.modelindex == BA_A_SPAWN || ent->s.modelindex == BA_A_OVERMIND ) &&
- ent->spawned )
+ if( ( ent->s.modelindex == BA_A_SPAWN ||
+ ent->s.modelindex == BA_A_OVERMIND ) &&
+ ent->spawned && ent->health > 0 )
{
VectorSubtract( self->s.origin, ent->s.origin, temp_v );
distance = VectorLength( temp_v );
@@ -523,12 +525,12 @@ static void freeBuildable( gentity_t *self )
/*
================
-A_CreepRecede
+AGeneric_CreepRecede
Called when an alien spawn dies
================
*/
-void A_CreepRecede( gentity_t *self )
+void AGeneric_CreepRecede( gentity_t *self )
{
//if the creep just died begin the recession
if( !( self->s.eFlags & EF_DEAD ) )
@@ -552,75 +554,135 @@ void A_CreepRecede( gentity_t *self )
G_FreeEntity( self );
}
+/*
+================
+AGeneric_Blast
+Called when an Alien buildable explodes after dead state
+================
+*/
+void AGeneric_Blast( gentity_t *self )
+{
+ vec3_t dir;
+ VectorCopy( self->s.origin2, dir );
-//==================================================================================
-
+ //do a bit of radius damage
+ G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
+ self->splashRadius, self, self->splashMethodOfDeath,
+ PTE_ALIENS );
+ //pretty events and item cleanup
+ self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed
+ G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
+ self->timestamp = level.time;
+ self->think = AGeneric_CreepRecede;
+ self->nextthink = level.time + 500;
+ self->r.contents = 0; //stop collisions...
+ trap_LinkEntity( self ); //...requires a relink
+}
/*
================
-ASpawn_Melt
+AGeneric_Die
-Called when an alien spawn dies
+Called when an Alien buildable is killed and enters a brief dead state prior to
+exploding.
================
*/
-void ASpawn_Melt( gentity_t *self )
+void AGeneric_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
{
- G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
- self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS );
+ G_RewardAttackers( self );
+ G_SetBuildableAnim( self, BANIM_DESTROY1, qtrue );
+ G_SetIdleBuildableAnim( self, BANIM_DESTROYED );
- //start creep recession
- if( !( self->s.eFlags & EF_DEAD ) )
+ self->die = nullDieFunction;
+ self->think = AGeneric_Blast;
+ self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
+
+ if( self->spawned )
+ self->nextthink = level.time + 5000;
+ else
+ self->nextthink = level.time; //blast immediately
+
+ if( attacker && attacker->client )
{
- self->s.eFlags |= EF_DEAD;
- G_AddEvent( self, EV_BUILD_DESTROY, 0 );
+ if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
+ {
+ G_TeamCommand( PTE_ALIENS,
+ va( "print \"%s ^3DESTROYED^7 by teammate %s^7\n\"",
+ BG_FindHumanNameForBuildable( self->s.modelindex ),
+ attacker->client->pers.netname ) );
+ }
+ G_LogPrintf( "Decon: %i %i %i: %s destroyed %s by %s\n",
+ attacker->client->ps.clientNum, self->s.modelindex, mod,
+ attacker->client->pers.netname,
+ BG_FindNameForBuildable( self->s.modelindex ),
+ modNames[ mod ] );
+ }
+}
- if( self->spawned )
- self->s.time = -level.time;
+/*
+================
+AGeneric_CreepCheck
+
+Tests for creep and kills the buildable if there is none
+================
+*/
+void AGeneric_CreepCheck( gentity_t *self )
+{
+ gentity_t *spawn;
+
+ spawn = self->parentNode;
+ if( !G_FindCreep( self ) )
+ {
+ if( spawn->inuse && spawn->enemy )
+ G_Damage( self, NULL, spawn->enemy, NULL, NULL, self->health, 0,
+ MOD_SUICIDE );
else
- self->s.time = -( level.time -
- (int)( (float)CREEP_SCALEDOWN_TIME *
- ( 1.0f - ( (float)( level.time - self->buildTime ) /
- (float)BG_FindBuildTimeForBuildable( self->s.modelindex ) ) ) ) );
+ G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
+ return;
}
+ G_CreepSlow( self );
+}
- //not dead yet
- if( ( self->timestamp + 10000 ) > level.time )
- self->nextthink = level.time + 500;
- else //dead now
- G_FreeEntity( self );
+/*
+================
+AGeneric_Think
+
+A generic think function for Alien buildables
+================
+*/
+void AGeneric_Think( gentity_t *self )
+{
+ self->powered = G_IsOvermindBuilt( );
+ self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
+ AGeneric_CreepCheck( self );
}
/*
================
-ASpawn_Blast
+AGeneric_Pain
-Called when an alien spawn dies
+A generic pain function for Alien buildables
================
*/
-void ASpawn_Blast( gentity_t *self )
+void AGeneric_Pain( gentity_t *self, gentity_t *attacker, int damage )
{
- vec3_t dir;
+ if( rand( ) % 1 )
+ G_SetBuildableAnim( self, BANIM_PAIN1, qfalse );
+ else
+ G_SetBuildableAnim( self, BANIM_PAIN2, qfalse );
+}
- VectorCopy( self->s.origin2, dir );
- //do a bit of radius damage
- G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
- self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS );
- //pretty events and item cleanup
- self->s.eFlags |= EF_NODRAW; //don't draw the model once it's destroyed
- G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
- self->timestamp = level.time;
- self->think = ASpawn_Melt;
- self->nextthink = level.time + 500; //wait .5 seconds before damaging others
- self->r.contents = 0; //stop collisions...
- trap_LinkEntity( self ); //...requires a relink
-}
+//==================================================================================
+
+
+
/*
================
@@ -636,7 +698,7 @@ void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
G_SetIdleBuildableAnim( self, BANIM_DESTROYED );
self->die = nullDieFunction;
- self->think = ASpawn_Blast;
+ self->think = AGeneric_Blast;
if( self->spawned )
self->nextthink = level.time + 5000;
@@ -823,124 +885,6 @@ void AOvermind_Think( gentity_t *self )
-
-//==================================================================================
-
-
-
-
-
-
-/*
-================
-AGeneric_Blast
-
-Called when an Alien buildable explodes after dead state
-================
-*/
-void AGeneric_Blast( gentity_t *self )
-{
- vec3_t dir;
-
- VectorCopy( self->s.origin2, dir );
-
- //do a bit of radius damage
- G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
- self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS );
-
- //pretty events and item cleanup
- self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed
- G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
- self->timestamp = level.time;
- self->think = A_CreepRecede;
- self->nextthink = level.time + 500; //wait .5 seconds before damaging others
-
- self->r.contents = 0; //stop collisions...
- trap_LinkEntity( self ); //...requires a relink
-}
-
-/*
-================
-AGeneric_Die
-
-Called when an Alien buildable is killed and enters a brief dead state prior to
-exploding.
-================
-*/
-void AGeneric_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
-{
- G_RewardAttackers( self );
- G_SetBuildableAnim( self, BANIM_DESTROY1, qtrue );
- G_SetIdleBuildableAnim( self, BANIM_DESTROYED );
-
- self->die = nullDieFunction;
- self->think = AGeneric_Blast;
- self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
-
- if( self->spawned )
- self->nextthink = level.time + 5000;
- else
- self->nextthink = level.time; //blast immediately
-
- if( attacker && attacker->client )
- {
- if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- G_TeamCommand( PTE_ALIENS,
- va( "print \"%s ^3DESTROYED^7 by teammate %s^7\n\"",
- BG_FindHumanNameForBuildable( self->s.modelindex ),
- attacker->client->pers.netname ) );
- }
- G_LogPrintf( "Decon: %i %i %i: %s destroyed %s by %s\n",
- attacker->client->ps.clientNum, self->s.modelindex, mod,
- attacker->client->pers.netname,
- BG_FindNameForBuildable( self->s.modelindex ),
- modNames[ mod ] );
- }
-}
-
-/*
-================
-AGeneric_Think
-
-A generic think function for Alien buildables
-================
-*/
-void AGeneric_Think( gentity_t *self )
-{
-
- self->powered = G_IsOvermindBuilt( );
-
- //if there is no creep nearby die
- if( !G_FindCreep( self ) )
- {
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
- }
-
- G_CreepSlow( self );
-
- self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
-}
-
-/*
-================
-AGeneric_Pain
-
-A generic pain function for Alien buildables
-================
-*/
-void AGeneric_Pain( gentity_t *self, gentity_t *attacker, int damage )
-{
- if( rand( ) % 1 )
- G_SetBuildableAnim( self, BANIM_PAIN1, qfalse );
- else
- G_SetBuildableAnim( self, BANIM_PAIN2, qfalse );
-}
-
-
-
-
//==================================================================================
@@ -1093,8 +1037,6 @@ void ABarricade_Touch( gentity_t *self, gentity_t *other, trace_t *trace )
-void AAcidTube_Think( gentity_t *self );
-
/*
================
AAcidTube_Think
@@ -1111,21 +1053,15 @@ void AAcidTube_Think( gentity_t *self )
gentity_t *enemy;
self->powered = G_IsOvermindBuilt( );
+ self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
VectorAdd( self->s.origin, range, maxs );
VectorSubtract( self->s.origin, range, mins );
- //if there is no creep nearby die
- if( !G_FindCreep( self ) )
- {
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
- }
-
- G_CreepSlow( self );
+ AGeneric_CreepCheck( self );
// attack nearby humans
- if( self->spawned && self->health && G_FindOvermind( self ) )
+ if( self->spawned && self->health > 0 && G_FindOvermind( self ) )
{
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
for( i = 0; i < num; i++ )
@@ -1152,8 +1088,6 @@ void AAcidTube_Think( gentity_t *self )
}
}
}
-
- self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
}
@@ -1181,18 +1115,12 @@ void AHive_Think( gentity_t *self )
vec3_t dirToTarget;
self->powered = G_IsOvermindBuilt( );
-
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
VectorAdd( self->s.origin, range, maxs );
VectorSubtract( self->s.origin, range, mins );
- //if there is no creep nearby die
- if( !G_FindCreep( self ) )
- {
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
- }
+ AGeneric_CreepCheck( self );
if( self->timestamp < level.time )
self->active = qfalse; //nothing has returned in HIVE_REPEAT seconds, forget about it
@@ -1228,8 +1156,6 @@ void AHive_Think( gentity_t *self )
}
}
}
-
- G_CreepSlow( self );
}
/*
@@ -1442,6 +1368,10 @@ Think for alien hovel
void AHovel_Think( gentity_t *self )
{
self->powered = G_IsOvermindBuilt( );
+ self->nextthink = level.time + 200;
+
+ AGeneric_CreepCheck( self );
+
if( self->spawned )
{
if( self->active )
@@ -1449,10 +1379,6 @@ void AHovel_Think( gentity_t *self )
else
G_SetIdleBuildableAnim( self, BANIM_IDLE1 );
}
-
- G_CreepSlow( self );
-
- self->nextthink = level.time + 200;
}
/*
@@ -1464,25 +1390,6 @@ Die for alien hovel
*/
void AHovel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
{
- vec3_t dir;
-
- G_RewardAttackers( self );
-
- VectorCopy( self->s.origin2, dir );
-
- //do a bit of radius damage
- G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
- self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS );
-
- //pretty events and item cleanup
- self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed
- G_AddEvent( self, EV_ALIEN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
- self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
- self->timestamp = level.time;
- self->think = ASpawn_Melt;
- self->nextthink = level.time + 500; //wait .5 seconds before damaging others
- self->die = nullDieFunction;
-
//if the hovel is occupied free the occupant
if( self->active )
{
@@ -1508,25 +1415,9 @@ void AHovel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
//client leaves hovel
builder->client->ps.stats[ STAT_STATE ] &= ~SS_HOVELING;
}
-
- self->r.contents = 0; //stop collisions...
- trap_LinkEntity( self ); //...requires a relink
-
- if( attacker && attacker->client )
- {
- if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- G_TeamCommand( PTE_ALIENS,
- va( "print \"%s ^3DESTROYED^7 by teammate %s^7\n\"",
- BG_FindHumanNameForBuildable( self->s.modelindex ),
- attacker->client->pers.netname ) );
- }
- G_LogPrintf( "Decon: %i %i %i: %s destroyed %s by %s\n",
- attacker->client->ps.clientNum, self->s.modelindex, mod,
- attacker->client->pers.netname,
- BG_FindNameForBuildable( self->s.modelindex ),
- modNames[ mod ] );
- }
+
+ AGeneric_Die( self, inflictor, attacker, damage, mod );
+ self->nextthink = level.time;
}
@@ -1710,17 +1601,9 @@ void ATrapper_Think( gentity_t *self )
int firespeed = BG_FindFireSpeedForBuildable( self->s.modelindex );
self->powered = G_IsOvermindBuilt( );
-
- G_CreepSlow( self );
-
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
- //if there is no creep nearby die
- if( !G_FindCreep( self ) )
- {
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
- }
+ AGeneric_CreepCheck( self );
if( self->spawned && G_FindOvermind( self ) )
{
@@ -1950,6 +1833,9 @@ void HDCC_Think( gentity_t *self )
//==================================================================================
+void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker,
+ int damage, int mod );
+
/*
================
HMedistat_Die
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 97e32929..38292c69 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -244,7 +244,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define ASPAWN_HEALTH ABHM(250)
#define ASPAWN_REGEN 8
#define ASPAWN_SPLASHDAMAGE 50
-#define ASPAWN_SPLASHRADIUS 50
+#define ASPAWN_SPLASHRADIUS 100
#define ASPAWN_CREEPSIZE 120
#define ASPAWN_VALUE 100
@@ -253,7 +253,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define BARRICADE_HEALTH ABHM(300)
#define BARRICADE_REGEN 14
#define BARRICADE_SPLASHDAMAGE 50
-#define BARRICADE_SPLASHRADIUS 50
+#define BARRICADE_SPLASHRADIUS 100
#define BARRICADE_CREEPSIZE 120
#define BARRICADE_SHRINKPROP 0.25f
#define BARRICADE_SHRINKTIMEOUT 500
@@ -264,7 +264,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define BOOSTER_HEALTH ABHM(150)
#define BOOSTER_REGEN 8
#define BOOSTER_SPLASHDAMAGE 50
-#define BOOSTER_SPLASHRADIUS 50
+#define BOOSTER_SPLASHRADIUS 100
#define BOOSTER_CREEPSIZE 120
#define BOOSTER_REGEN_MOD 3.0f
#define BOOSTER_VALUE 120
@@ -275,7 +275,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define ACIDTUBE_HEALTH ABHM(125)
#define ACIDTUBE_REGEN 10
#define ACIDTUBE_SPLASHDAMAGE 50
-#define ACIDTUBE_SPLASHRADIUS 50
+#define ACIDTUBE_SPLASHRADIUS 100
#define ACIDTUBE_CREEPSIZE 120
#define ACIDTUBE_DAMAGE 8
#define ACIDTUBE_RANGE 300.0f