/** * Adds momentum for killing a player. * * G_AddMomentumEnd has to be called after all G_AddMomentum*Step steps are *done. */ float G_AddMomentumForKillingStep(gentity_t* victim, gentity_t* attacker, float share) { float value; team_t team; // sanity check victim if (!victim || !victim->client) { return 0.0f; } // sanity check attacker if (!attacker || !attacker->client) { return 0.0f; } value = BG_GetValueOfPlayer(&victim->client->ps) * MOMENTUM_PER_CREDIT * share; team = (team_t) attacker->client->pers.team; return AddMomentum(CONF_KILLING, team, value, attacker, true); }
/* ================== G_RewardAttackers Function to distribute rewards to entities that killed this one. ================== */ void G_RewardAttackers( gentity_t *self ) { float value, reward; int playerNum, enemyDamage, maxHealth, damageShare; gentity_t *player; team_t ownTeam, playerTeam; confidence_reason_t reason; confidence_qualifier_t qualifier; // Only reward killing players and buildables if ( self->client ) { ownTeam = self->client->pers.teamSelection; maxHealth = self->client->ps.stats[ STAT_MAX_HEALTH ]; value = ( float )BG_GetValueOfPlayer( &self->client->ps ); } else if ( self->s.eType == ET_BUILDABLE ) { ownTeam = self->buildableTeam; maxHealth = BG_Buildable( self->s.modelindex )->health; value = ( float )BG_Buildable( self->s.modelindex )->value; // Give partial credits for buildables in construction if ( !self->spawned ) { value *= ( float )( level.time - self->creationTime ) / BG_Buildable( self->s.modelindex )->buildTime; } } else { return; } enemyDamage = 0; // Sum up damage dealt by enemies for ( playerNum = 0; playerNum < level.maxclients; playerNum++ ) { player = &g_entities[ playerNum ]; playerTeam = player->client->pers.teamSelection; // Player must be on the other team if ( playerTeam == ownTeam || playerTeam <= TEAM_NONE || playerTeam >= NUM_TEAMS ) { continue; } enemyDamage += self->credits[ playerNum ]; } if ( enemyDamage <= 0 ) { return; } // Give individual rewards for ( playerNum = 0; playerNum < level.maxclients; playerNum++ ) { player = &g_entities[ playerNum ]; playerTeam = player->client->pers.teamSelection; damageShare = self->credits[ playerNum ]; // Clear reward array self->credits[ playerNum ] = 0; // 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 ) { continue; } reward = value * ( damageShare / ( float )maxHealth ); if ( reward <= 0.0f ) { continue; } if ( self->s.eType == ET_BUILDABLE ) { G_AddConfidenceToScore( player, reward ); switch ( self->s.modelindex ) { case BA_A_OVERMIND: case BA_H_REACTOR: reason = CONF_REAS_DESTR_CRUCIAL; break; case BA_A_ACIDTUBE: case BA_A_TRAPPER: case BA_A_HIVE: case BA_H_MGTURRET: case BA_H_TESLAGEN: reason = CONF_REAS_DESTR_AGGRESSIVE; break; default: reason = CONF_REAS_DESTR_SUPPORT; } qualifier = CONF_QUAL_NONE; G_AddConfidence( playerTeam, CONFIDENCE_DESTRUCTION, reason, qualifier, reward, player ); } else { G_AddCreditsToScore( player, ( int )reward ); G_AddCreditToClient( player->client, ( short )reward, qtrue ); // Give confidence for killing non-naked players outside the friendly base switch ( self->client->ps.stats[ STAT_CLASS ] ) { case PCL_ALIEN_LEVEL0: case PCL_ALIEN_BUILDER0: case PCL_ALIEN_BUILDER0_UPG: break; case PCL_HUMAN: // Treat a human just wearing light armor as naked if ( ( int )value <= BG_Class( PCL_HUMAN )->value + ( BG_Upgrade( UP_LIGHTARMOUR )->price / 2 ) ) { break; } default: if ( G_InsideBase( player, qtrue ) || G_InsideBase( self, qfalse ) ) { break; } qualifier = CONF_QUAL_OUTSIDE_OWN_BASE; G_AddConfidence( playerTeam, CONFIDENCE_KILLING, CONF_REAS_KILLING, qualifier, reward * CONFIDENCE_PER_CREDIT, player ); } } } }
/** * @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_Buildable( self->s.modelindex )->value; // 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 ]; } 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 ]; // Clear reward array self->credits[ playerNum ] = 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, share ); } else { // Add score G_AddCreditsToScore( player, ( int )reward ); // Add credits G_AddCreditToClient( player->client, ( short )reward, qtrue ); // Add momentum G_AddMomentumForKillingStep( self, player, share ); } } // Complete momentum modification G_AddMomentumEnd(); }
/* ================== G_RewardAttackers Function to distribute rewards to entities that killed this one. Returns the total damage dealt. ================== */ float G_RewardAttackers( gentity_t *self ) { float value, totalDamage = 0; int team, i, maxHealth = 0; int alienCredits = 0, humanCredits = 0; gentity_t *player; // Total up all the damage done by non-teammates for( i = 0; i < level.maxclients; i++ ) { player = g_entities + i; if( !OnSameTeam( self, player ) || self->buildableTeam != player->client->ps.stats[ STAT_TEAM ] ) totalDamage += (float)self->credits[ i ]; } if( totalDamage <= 0.0f ) return 0.0f; // Only give credits for killing players and buildables if( self->client ) { value = BG_GetValueOfPlayer( &self->client->ps ); team = self->client->pers.teamSelection; maxHealth = self->client->ps.stats[ STAT_MAX_HEALTH ]; } else if( self->s.eType == ET_BUILDABLE ) { value = BG_Buildable( self->s.modelindex )->value; // only give partial credits for a buildable not yet completed if( !self->spawned ) { value *= (float)( level.time - self->buildTime ) / BG_Buildable( self->s.modelindex )->buildTime; } team = self->buildableTeam; maxHealth = BG_Buildable( self->s.modelindex )->health; } else return totalDamage; // Give credits and empty the array for( i = 0; i < level.maxclients; i++ ) { int stageValue = value * self->credits[ i ] / totalDamage; player = g_entities + i; if( player->client->pers.teamSelection != team ) { if( totalDamage < maxHealth ) stageValue *= totalDamage / maxHealth; if( !self->credits[ i ] || player->client->ps.stats[ STAT_TEAM ] == team ) continue; AddScore( player, stageValue ); // killing buildables earns score, but not credits if( self->s.eType != ET_BUILDABLE ) { G_AddCreditToClient( player->client, stageValue, qtrue ); // add to stage counters if( player->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) alienCredits += stageValue; else if( player->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) humanCredits += stageValue; } } self->credits[ i ] = 0; } if( alienCredits ) { trap_Cvar_Set( "g_alienCredits", va( "%d", g_alienCredits.integer + alienCredits ) ); trap_Cvar_Update( &g_alienCredits ); } if( humanCredits ) { trap_Cvar_Set( "g_humanCredits", va( "%d", g_humanCredits.integer + humanCredits ) ); trap_Cvar_Update( &g_humanCredits ); } return totalDamage; }