From b4f7bd74f46219909dcb116d4448a378edc405b7 Mon Sep 17 00:00:00 2001 From: Theriaca Date: Sat, 26 Jan 2019 07:19:44 +0100 Subject: rewrite and optimize G_OverflowCredits() - now always prioritizes poor players - synchronizes PERS_CREDIT once per loop, instead of constantly additionally, rename: - G_AddCreditToClient -> G_AddFundsToClient - G_OverflowCredits -> G_OverflowFunds - 'credit(s)' parameters -> 'funds' --- src/game/g_client.c | 180 +++++++++++++++++----------------------------------- 1 file changed, 57 insertions(+), 123 deletions(-) (limited to 'src/game/g_client.c') diff --git a/src/game/g_client.c b/src/game/g_client.c index 8fb61fe..5b3f122 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -79,180 +79,114 @@ void SP_info_human_intermission( gentity_t *ent ) { } +static int compare_client_funds(const void *c1, const void *c2) +{ + return (((const gclient_t *)c1)->pers.credit - ((const gclient_t *)c2)->pers.credit); +} + /* =============== -G_OverflowCredits +G_OverflowFunds =============== */ -void G_OverflowCredits( gclient_t *doner, float credits ) +static void G_OverflowFunds(gclient_t *donor, float funds) { int i; - int maxCredits; - int clientNum; - float fractionalCredit = 0.0f; + int count = 0; + int max; + gclient_t *clients[MAX_CLIENTS]; - if( !g_creditOverflow.integer ) + if (!g_creditOverflow.integer || !funds) return; - if( doner->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) - { - int buffer = (int)floor(credits); + if (donor->ps.stats[STAT_PTEAM] == PTE_ALIENS) + max = ALIEN_MAX_KILLS; + else if (donor->ps.stats[STAT_PTEAM] == PTE_HUMANS) + max = HUMAN_MAX_CREDITS; - fractionalCredit = credits - buffer; - credits = buffer; - maxCredits = ALIEN_MAX_KILLS; - clientNum = level.lastCreditedAlien; - } - else if( doner->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) - { - maxCredits = HUMAN_MAX_CREDITS; - clientNum = level.lastCreditedHuman; - } - else - { - return; - } + // build a list of clients on the team + for (i = 0; i < level.maxclients; i++) { + gclient_t *target; - if( g_creditOverflow.integer == 1 ) - { - // distribute to everyone on team - gentity_t *vic; + target = level.clients + i; - i = 0; - while( credits > 0 && i < level.maxclients ) - { - i++; - clientNum++; - if( clientNum >= level.maxclients ) - clientNum = 0; - - vic = &g_entities[ clientNum ]; - if( vic->client->ps.stats[ STAT_PTEAM ] != doner->ps.stats[ STAT_PTEAM ] || - vic->client->ps.persistant[ PERS_CREDIT ] >= maxCredits ) - continue; + if (target->ps.stats[STAT_PTEAM] != donor->ps.stats[STAT_PTEAM]) + continue; - if( vic->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) - { - if( fractionalCredit > 0 ) - vic->client->pers.fractionalCredit += fractionalCredit; + clients[count++] = target; + } - if( vic->client->pers.fractionalCredit > 1.0f ) - { - int buffer; + // reorganize the list from poorest to richest + qsort(clients, count, sizeof(gclient_t*), compare_client_funds); - buffer = floor( vic->client->pers.fractionalCredit ); - vic->client->pers.fractionalCredit -= buffer; - credits += buffer; - } + for (i = 0; i < count; i++) { + gclient_t *target; + float buffer; - level.lastCreditedAlien = clientNum; - } - else - { - level.lastCreditedHuman = clientNum; - } + target = clients[i]; - if( vic->client->ps.persistant[ PERS_CREDIT ] + credits > maxCredits ) - { - if ( vic->client->pers.fractionalCredit > 0 ) { - fractionalCredit += vic->client->pers.fractionalCredit; - vic->client->pers.fractionalCredit = 0.0f; - } + if (!funds) + break; - credits -= maxCredits - vic->client->ps.persistant[ PERS_CREDIT ]; - vic->client->ps.persistant[ PERS_CREDIT ] = maxCredits; - } - else - { - vic->client->ps.persistant[ PERS_CREDIT ] += credits; - return; - } + if (target->ps.stats[STAT_PTEAM] == PTE_ALIENS) { + buffer = target->pers.credit + target->pers.fractionalCredit + funds - max; + } else { + funds = floor(funds); + buffer = target->pers.credit + funds - max; } - } - else if( g_creditOverflow.integer == 2 ) - { - // distribute by team rank - gclient_t *cl; - - for( i = 0; i < level.numPlayingClients && credits > 0; i++ ) - { - // get the client list sorted by rank - cl = &level.clients[ level.sortedClients[ i ] ]; - if( cl->ps.stats[ STAT_PTEAM ] != doner->ps.stats[ STAT_PTEAM ] || - cl->ps.persistant[ PERS_CREDIT ] >= maxCredits ) - continue; - - if( cl->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) - { - if( fractionalCredit > 0 ) - cl->pers.fractionalCredit += fractionalCredit; - - if( cl->pers.fractionalCredit > 1.0f ) - { - int buffer; - buffer = floor( cl->pers.fractionalCredit ); - cl->pers.fractionalCredit -= buffer; - credits += buffer; - } - } + if (buffer > 0) { + target->pers.credit = max; + target->pers.fractionalCredit = 0.0f; + } else { + target->pers.credit += floor(funds); + target->pers.fractionalCredit += funds - floor(funds); + } - if( cl->ps.persistant[ PERS_CREDIT ] + credits > maxCredits ) - { - if ( cl->pers.fractionalCredit > 0 ) { - fractionalCredit += cl->pers.fractionalCredit; - cl->pers.fractionalCredit = 0.0f; - } + funds = buffer; - credits -= maxCredits - cl->ps.persistant[ PERS_CREDIT ]; - cl->ps.persistant[ PERS_CREDIT ] = maxCredits; - } - else - { - cl->ps.persistant[ PERS_CREDIT ] += credits; - return; - } - } + // synchronize PERS_CREDIT + target->ps.persistant[PERS_CREDIT] = (int)target->pers.credit; } } /* =============== -G_AddCreditToClient +G_AddFundsToClient =============== */ -void G_AddCreditToClient(gclient_t *client, float credit, qboolean cap) +void G_AddFundsToClient(gclient_t *client, float funds, qboolean cap) { - if (!client || credit == 0) + if (!client || funds == 0) return; if (cap) { int max = 0; - float buffer = credit; + float buffer = funds; if (client->pers.teamSelection == PTE_ALIENS) { max = ALIEN_MAX_KILLS; - client->pers.fractionalCredit += credit; + client->pers.fractionalCredit += funds; if (client->pers.fractionalCredit > 1.0f) { - credit = floor(client->pers.fractionalCredit); - client->pers.fractionalCredit -= credit; + funds = floor(client->pers.fractionalCredit); + client->pers.fractionalCredit -= funds; } } else if (client->pers.teamSelection == PTE_HUMANS) { max = HUMAN_MAX_CREDITS; } - buffer = client->pers.credit + credit - max; + buffer = client->pers.credit + funds - max; if (buffer > 0) { - G_OverflowCredits(client, buffer + client->pers.fractionalCredit); + G_OverflowFunds(client, buffer + client->pers.fractionalCredit); client->pers.credit = max; client->pers.fractionalCredit = 0.0f; } else { - client->pers.credit += (short)credit; + client->pers.credit += (short)funds; } } else { - client->pers.credit += (short)credit; + client->pers.credit += (short)funds; } if (client->pers.credit < 0) -- cgit