diff options
Diffstat (limited to 'src/game/g_buildable.c')
-rw-r--r-- | src/game/g_buildable.c | 108 |
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; |