/** * @brief Function to distribute rewards to entities that killed this one. * @param self */ void G_RewardAttackers( gentity_t *self ) { float value, share, reward, enemyDamage, damageShare; int playerNum, maxHealth; gentity_t *player; team_t ownTeam, playerTeam; // Only reward killing players and buildables if ( self->client ) { ownTeam = (team_t) self->client->pers.team; maxHealth = self->client->ps.stats[ STAT_MAX_HEALTH ]; value = BG_GetValueOfPlayer( &self->client->ps ); } else if ( self->s.eType == ET_BUILDABLE ) { ownTeam = (team_t) self->buildableTeam; maxHealth = BG_Buildable( self->s.modelindex )->health; value = BG_IsMainStructure( &self->s ) ? MAIN_STRUCTURE_MOMENTUM_VALUE : BG_Buildable( self->s.modelindex )->buildPoints; // Give partial credits for buildables in construction if ( !self->spawned ) { value *= ( level.time - self->creationTime ) / ( float )BG_Buildable( self->s.modelindex )->buildTime; } } else { return; } // Sum up damage dealt by enemies enemyDamage = 0.0f; for ( playerNum = 0; playerNum < level.maxclients; playerNum++ ) { player = &g_entities[ playerNum ]; playerTeam = (team_t) player->client->pers.team; // Player must be on the other team if ( playerTeam == ownTeam || playerTeam <= TEAM_NONE || playerTeam >= NUM_TEAMS ) { continue; } enemyDamage += self->credits[ playerNum ].value; } if ( enemyDamage <= 0 ) { return; } // Give individual rewards for ( playerNum = 0; playerNum < level.maxclients; playerNum++ ) { player = &g_entities[ playerNum ]; playerTeam = (team_t) player->client->pers.team; damageShare = self->credits[ playerNum ].value; // Clear reward array self->credits[ playerNum ].value = 0.0f; // Player must be on the other team if ( playerTeam == ownTeam || playerTeam <= TEAM_NONE || playerTeam >= NUM_TEAMS ) { continue; } // Player must have dealt damage if ( damageShare <= 0.0f ) { continue; } share = damageShare / ( float )maxHealth; reward = value * share; if ( self->s.eType == ET_BUILDABLE ) { // Add score G_AddMomentumToScore( player, reward ); // Add momentum G_AddMomentumForDestroyingStep( self, player, reward ); } else { // Add score G_AddCreditsToScore( player, ( int )reward ); // Add credits G_AddCreditToClient( player->client, ( short )reward, true ); // Add momentum G_AddMomentumForKillingStep( self, player, share ); } } // Complete momentum modification G_AddMomentumEnd(); }
bool BG_IsMainStructure( entityState_t *es ) { if ( es->eType != ET_BUILDABLE ) return false; return BG_IsMainStructure( (buildable_t)es->modelindex ); }