summaryrefslogtreecommitdiff
path: root/src/game/g_buildable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/g_buildable.c')
-rw-r--r--src/game/g_buildable.c108
1 files changed, 50 insertions, 58 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 3e13ea6f..a64772b5 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -148,9 +148,6 @@ qboolean G_FindPower( gentity_t *self, qboolean searchUnspawned )
return self->parentNode != NULL;
}
- // Reset parent
- self->parentNode = NULL;
-
// Iterate through entities
for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ )
{
@@ -685,6 +682,9 @@ void AGeneric_CreepRecede( gentity_t *self )
{
self->s.eFlags |= EF_DEAD;
G_QueueBuildPoints( self );
+
+ G_RewardAttackers( self );
+
G_AddEvent( self, EV_BUILD_DESTROY, 0 );
if( self->spawned )
@@ -717,7 +717,7 @@ void AGeneric_Blast( gentity_t *self )
VectorCopy( self->s.origin2, dir );
//do a bit of radius damage
- G_SelectiveRadiusDamage( self->s.pos.trBase, self, self->splashDamage,
+ G_SelectiveRadiusDamage( self->s.pos.trBase, g_entities + self->killedBy, self->splashDamage,
self->splashRadius, self, self->splashMethodOfDeath,
TEAM_ALIENS );
@@ -742,11 +742,11 @@ 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->killedBy = attacker - g_entities;
self->think = AGeneric_Blast;
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
self->powered = qfalse;
@@ -773,8 +773,8 @@ void AGeneric_CreepCheck( gentity_t *self )
spawn = self->parentNode;
if( !G_FindCreep( self ) )
{
- if( spawn && self->killedBy != ENTITYNUM_NONE )
- G_Damage( self, NULL, g_entities + self->killedBy, NULL, NULL,
+ if( spawn )
+ G_Damage( self, NULL, g_entities + spawn->killedBy, NULL, NULL,
self->health, 0, MOD_NOCREEP );
else
G_Damage( self, NULL, NULL, NULL, NULL, self->health, 0, MOD_NOCREEP );
@@ -818,35 +818,6 @@ void AGeneric_Pain( gentity_t *self, gentity_t *attacker, int damage )
//==================================================================================
-
-
-
-/*
-================
-ASpawn_Die
-
-Called when an alien spawn dies
-================
-*/
-void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
-{
- int i;
-
- AGeneric_Die( self, inflictor, attacker, damage, mod );
-
- // All supported structures that no longer have creep will have been killed
- // by whoever killed this structure
- for( i = MAX_CLIENTS; i < level.num_entities; i++ )
- {
- gentity_t *ent = g_entities + i;
-
- if( !ent->inuse || ent->health <= 0 || ent->s.eType != ET_BUILDABLE ||
- ent->parentNode != self )
- continue;
- ent->killedBy = attacker - g_entities;
- }
-}
-
/*
================
ASpawn_Think
@@ -1527,13 +1498,19 @@ static void G_SuicideIfNoPower( gentity_t *self )
if( self->buildableTeam != TEAM_HUMANS )
return;
- if( G_Reactor( ) && !self->parentNode )
+ if( G_Reactor( ) && !self->powered )
{
// If no parent for x seconds then disappear
if( self->count < 0 )
self->count = level.time;
else if( self->count > 0 && ( ( level.time - self->count ) > HUMAN_BUILDABLE_INACTIVE_TIME ) )
- G_Damage( self, NULL, NULL, NULL, NULL, self->health, 0, MOD_SUICIDE );
+ {
+ if( self->parentNode )
+ G_Damage( self, NULL, g_entities + self->parentNode->killedBy,
+ NULL, NULL, self->health, 0, MOD_NOCREEP );
+ else
+ G_Damage( self, NULL, NULL, NULL, NULL, self->health, 0, MOD_NOCREEP );
+ }
}
else
{
@@ -1583,6 +1560,7 @@ void HSpawn_Disappear( gentity_t *self )
self->s.eFlags |= EF_NODRAW; //don't draw the model once its destroyed
self->timestamp = level.time;
G_QueueBuildPoints( self );
+ G_RewardAttackers( self );
G_FreeEntity( self );
}
@@ -1607,11 +1585,12 @@ void HSpawn_Blast( gentity_t *self )
self->timestamp = level.time;
//do some radius damage
- G_RadiusDamage( self->s.pos.trBase, self, self->splashDamage,
+ G_RadiusDamage( self->s.pos.trBase, g_entities + self->killedBy, self->splashDamage,
self->splashRadius, self, self->splashMethodOfDeath );
// begin freeing build points
G_QueueBuildPoints( self );
+ G_RewardAttackers( self );
// turn into an explosion
self->s.eType = ET_EVENTS + EV_HUMAN_BUILDABLE_EXPLOSION;
self->freeAfterEvent = qtrue;
@@ -1628,11 +1607,11 @@ Called when a human spawn dies
*/
void HSpawn_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->killedBy = attacker - g_entities;
self->powered = qfalse; //free up power
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
@@ -1718,6 +1697,7 @@ static void HRepeater_Die( gentity_t *self, gentity_t *inflictor, gentity_t *att
G_SetIdleBuildableAnim( self, BANIM_DESTROYED );
self->die = nullDieFunction;
+ self->killedBy = attacker - g_entities;
self->powered = qfalse; //free up power
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
@@ -2496,19 +2476,34 @@ G_QueueBuildPoints
*/
void G_QueueBuildPoints( gentity_t *self )
{
- gentity_t *killer = NULL;
gentity_t *powerEntity;
+ int i;
+ int damageTotal = 0;
+ int queuePoints = 0;
+ double queueFraction = 0;
- if( self->killedBy != ENTITYNUM_NONE )
- killer = &g_entities[ self->killedBy ];
-
- if( killer && killer->client &&
- killer->client->ps.stats[ STAT_TEAM ] == self->buildableTeam )
+ for( i = 0; i < MAX_CLIENTS; i++ )
{
- // Don't take away build points if killed by a teammate
- // deconstructing an egg/overmind (MOD_NOCREEP)
- return;
+ gentity_t *player = g_entities + i;
+
+ if( !player->client )
+ continue;
+
+ damageTotal += self->credits[ i ];
+
+ if( self->buildableTeam != player->client->pers.teamSelection )
+ queueFraction += (double) self->credits[ i ];
}
+
+ if( damageTotal > 0 )
+ queueFraction = queueFraction / (double) damageTotal;
+ else // all damage was done by nonclients, so queue everything
+ queueFraction = 1.0;
+
+ queuePoints = (int) ( queueFraction * (double) BG_Buildable( self->s.modelindex )->buildPoints );
+
+ if( !queuePoints )
+ return;
switch( self->buildableTeam )
{
@@ -2520,8 +2515,7 @@ void G_QueueBuildPoints( gentity_t *self )
if( !level.alienBuildPointQueue )
level.alienNextQueueTime = level.time + g_alienBuildQueueTime.integer;
- level.alienBuildPointQueue +=
- BG_Buildable( self->s.modelindex )->buildPoints;
+ level.alienBuildPointQueue += queuePoints;
break;
case TEAM_HUMANS:
@@ -2540,8 +2534,7 @@ void G_QueueBuildPoints( gentity_t *self )
level.time + nqt < level.humanNextQueueTime )
level.humanNextQueueTime = level.time + nqt;
- level.humanBuildPointQueue +=
- BG_Buildable( self->s.modelindex )->buildPoints;
+ level.humanBuildPointQueue += queuePoints;
break;
case BA_H_REPEATER:
@@ -2558,8 +2551,7 @@ void G_QueueBuildPoints( gentity_t *self )
level.time + nqt < zone->nextQueueTime )
zone->nextQueueTime = level.time + nqt;
- zone->queuedBuildPoints +=
- BG_Buildable( self->s.modelindex )->buildPoints;
+ zone->queuedBuildPoints += queuePoints;
}
break;
@@ -2970,7 +2962,7 @@ void G_FreeMarkedBuildables( gentity_t *deconner, char *readable, int rsize,
if( removalCounts[ bNum ] == 0 )
totalListItems++;
- G_Damage( ent, NULL, NULL, NULL, NULL, ent->health, 0, MOD_DECONSTRUCT );
+ G_Damage( ent, NULL, NULL, NULL, NULL, ent->health, 0, MOD_REPLACE );
removalCounts[ bNum ]++;
@@ -3496,7 +3488,7 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori
switch( buildable )
{
case BA_A_SPAWN:
- built->die = ASpawn_Die;
+ built->die = AGeneric_Die;
built->think = ASpawn_Think;
built->pain = AGeneric_Pain;
break;
@@ -3536,7 +3528,7 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori
break;
case BA_A_OVERMIND:
- built->die = ASpawn_Die;
+ built->die = AGeneric_Die;
built->think = AOvermind_Think;
built->pain = AGeneric_Pain;
break;