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_active.c | 4 +- src/game/g_admin.c | 8 +-- src/game/g_buildable.c | 8 +-- src/game/g_client.c | 180 ++++++++++++++++--------------------------------- src/game/g_cmds.c | 26 +++---- src/game/g_combat.c | 18 ++--- src/game/g_local.h | 2 +- 7 files changed, 90 insertions(+), 156 deletions(-) diff --git a/src/game/g_active.c b/src/game/g_active.c index 63af175..3a989cc 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -1558,11 +1558,11 @@ static void ClientGradualFunds( gentity_t *ent ) switch ( ent->client->ps.stats[ STAT_PTEAM ] ) { case PTE_ALIENS: - G_AddCreditToClient( ent->client, FREEKILL_ALIEN, qtrue ); + G_AddFundsToClient( ent->client, FREEKILL_ALIEN, qtrue ); break; case PTE_HUMANS: - G_AddCreditToClient( ent->client, FREEKILL_HUMAN, qtrue ); + G_AddFundsToClient( ent->client, FREEKILL_HUMAN, qtrue ); break; } diff --git a/src/game/g_admin.c b/src/game/g_admin.c index cb42e31..9a331fe 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -5431,14 +5431,14 @@ qboolean G_admin_denyweapon( gentity_t *ent, int skiparg ) BG_InventoryContainsUpgrade( UP_GRENADE, vic->client->ps.stats ) ) { BG_RemoveUpgradeFromInventory( UP_GRENADE, vic->client->ps.stats ); - G_AddCreditToClient( vic->client, (short)BG_FindPriceForUpgrade( UP_GRENADE ), qfalse ); + G_AddFundsToClient( vic->client, (short)BG_FindPriceForUpgrade( UP_GRENADE ), qfalse ); } if( BG_InventoryContainsWeapon( weapon, vic->client->ps.stats ) ) { int maxAmmo, maxClips; BG_RemoveWeaponFromInventory( weapon, vic->client->ps.stats ); - G_AddCreditToClient( vic->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); + G_AddFundsToClient( vic->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); BG_AddWeaponToInventory( WP_MACHINEGUN, vic->client->ps.stats ); BG_FindAmmoForWeapon( WP_MACHINEGUN, &maxAmmo, &maxClips ); @@ -5490,7 +5490,7 @@ qboolean G_admin_denyweapon( gentity_t *ent, int skiparg ) vic->client->pers.classSelection = PCL_ALIEN_LEVEL0; cost = BG_ClassCanEvolveFromTo( PCL_ALIEN_LEVEL0, class, 9, 0 ); if( cost < 0 ) cost = 0; - G_AddCreditToClient( vic->client, cost, qfalse ); + G_AddFundsToClient( vic->client, cost, qfalse ); ClientUserinfoChanged( pids[ 0 ], qfalse ); VectorCopy( infestOrigin, vic->s.pos.trBase ); ClientSpawn( vic, vic, vic->s.pos.trBase, vic->s.apos.trBase ); @@ -10556,7 +10556,7 @@ qboolean G_admin_give(gentity_t *ent, int skiparg) goto invalid_target; } - G_AddCreditToClient(target->client, amount, qtrue); + G_AddFundsToClient(target->client, amount, qtrue); AP(va("print \"^3!give: ^7%s^7 was given %i %s%s by ^7%s^7\n\"", target->client->pers.netname, amount, currency, (abs(amount) != 1 ? "s" : ""), diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index f39dbd7..2e01960 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -725,9 +725,9 @@ void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) { if( self->s.modelindex == BA_A_OVERMIND ) - G_AddCreditToClient( attacker->client, OVERMIND_VALUE, qtrue ); + G_AddFundsToClient( attacker->client, OVERMIND_VALUE, qtrue ); else if( self->s.modelindex == BA_A_SPAWN ) - G_AddCreditToClient( attacker->client, ASPAWN_VALUE, qtrue ); + G_AddFundsToClient( attacker->client, ASPAWN_VALUE, qtrue ); } else { @@ -2702,9 +2702,9 @@ void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) { if( self->s.modelindex == BA_H_REACTOR ) - G_AddCreditToClient( attacker->client, REACTOR_VALUE, qtrue ); + G_AddFundsToClient( attacker->client, REACTOR_VALUE, qtrue ); else if( self->s.modelindex == BA_H_SPAWN ) - G_AddCreditToClient( attacker->client, HSPAWN_VALUE, qtrue ); + G_AddFundsToClient( attacker->client, HSPAWN_VALUE, qtrue ); } else { 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) diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 8822d1e..aa80248 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -418,7 +418,7 @@ void Cmd_Give_f( gentity_t *ent ) if( give_all || Q_stricmpn( name, "funds", 5 ) == 0 ) { int credits = give_all ? HUMAN_MAX_CREDITS : atoi( name + 6 ); - G_AddCreditToClient( ent->client, credits, qtrue ); + G_AddFundsToClient( ent->client, credits, qtrue ); } if( give_all || Q_stricmp( name, "stamina" ) == 0 ) @@ -3286,7 +3286,7 @@ void Cmd_Class_f( gentity_t *ent ) ent->client->pers.evolveHealthFraction = 1.0f; //remove credit - G_AddCreditToClient( ent->client, -(short)numLevels, qtrue ); + G_AddFundsToClient( ent->client, -(short)numLevels, qtrue ); ent->client->pers.classSelection = newClass; ClientUserinfoChanged( clientNum, qfalse ); VectorCopy( infestOrigin, ent->s.pos.trBase ); @@ -3976,7 +3976,7 @@ void Cmd_Buy_f( gentity_t *ent ) ent->client->ps.stats[ STAT_MISC ] = 0; //subtract from funds - G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); + G_AddFundsToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); } else if( upgrade != UP_NONE ) { @@ -4049,7 +4049,7 @@ void Cmd_Buy_f( gentity_t *ent ) G_GiveClientMaxAmmo( ent, qtrue ); //subtract from funds - G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); + G_AddFundsToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); } else { @@ -4116,7 +4116,7 @@ void Cmd_Sell_f( gentity_t *ent ) BG_RemoveWeaponFromInventory( weapon, ent->client->ps.stats ); //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); + G_AddFundsToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); } //if we have this weapon selected, force a new selection @@ -4140,7 +4140,7 @@ void Cmd_Sell_f( gentity_t *ent ) G_GiveClientMaxAmmo( ent, qtrue ); //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); + G_AddFundsToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); } } else if( !Q_stricmp( s, "weapons" ) ) @@ -4161,7 +4161,7 @@ void Cmd_Sell_f( gentity_t *ent ) BG_RemoveWeaponFromInventory( i, ent->client->ps.stats ); //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); + G_AddFundsToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); } //if we have this weapon selected, force a new selection @@ -4197,7 +4197,7 @@ void Cmd_Sell_f( gentity_t *ent ) } //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); + G_AddFundsToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); } } } @@ -5030,7 +5030,7 @@ void Cmd_PTRCRestore_f( gentity_t *ent ) // set the correct credit etc. ent->client->ps.persistant[ PERS_CREDIT ] = 0; - G_AddCreditToClient( ent->client, connection->clientCredit, qtrue ); + G_AddFundsToClient( ent->client, connection->clientCredit, qtrue ); ent->client->pers.score = connection->clientScore; ent->client->pers.enterTime = connection->clientEnterTime; } @@ -5298,12 +5298,12 @@ static void Cmd_Ignore_f( gentity_t *ent ) } // transfer credits - G_AddCreditToClient( ent->client, -creds, qfalse ); + G_AddFundsToClient( ent->client, -creds, qfalse ); trap_SendServerCommand( ent-g_entities, va( "print \"share: transferred %d %s to %s^7.\n\"", creds, ( team == PTE_HUMANS ) ? "credits" : "evolvepoints", level.clients[ clientNum ].pers.netname ) ); - G_AddCreditToClient( &(level.clients[ clientNum ]), creds, qtrue ); + G_AddFundsToClient( &(level.clients[ clientNum ]), creds, qtrue ); trap_SendServerCommand( clientNum, va( "print \"You have received %d %s from %s^7.\n\"", creds, ( team == PTE_HUMANS ) ? "credits" : "evolvepoints", @@ -5399,7 +5399,7 @@ static void Cmd_Ignore_f( gentity_t *ent ) new_credits = max; } if( amounts[ i ] ) { - G_AddCreditToClient( &(level.clients[ i ]), amounts[ i ], qtrue ); + G_AddFundsToClient( &(level.clients[ i ]), amounts[ i ], qtrue ); donated = qtrue; value -= amounts[ i ]; if( value < portion ) break; @@ -5408,7 +5408,7 @@ static void Cmd_Ignore_f( gentity_t *ent ) } // transfer funds - G_AddCreditToClient( ent->client, value - total, qtrue ); + G_AddFundsToClient( ent->client, value - total, qtrue ); for( i = 0; i < level.maxclients; i++ ) if( amounts[ i ] ) { trap_SendServerCommand( i, diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 7b58f1f..d834fcd 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -279,9 +279,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( !g_retribution.integer ) { if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) - G_AddCreditToClient( attacker->client, -FREEKILL_ALIEN, qtrue ); + G_AddFundsToClient( attacker->client, -FREEKILL_ALIEN, qtrue ); else if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) - G_AddCreditToClient( attacker->client, -FREEKILL_HUMAN, qtrue ); + G_AddFundsToClient( attacker->client, -FREEKILL_HUMAN, qtrue ); } } else @@ -386,8 +386,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int price = g_entities[ i ].client->ps.persistant[ PERS_CREDIT ]; if ( price ) { - G_AddCreditToClient( self->client, price, qtrue ); - G_AddCreditToClient( g_entities[ i ].client, -price, qtrue ); + G_AddFundsToClient( self->client, price, qtrue ); + G_AddFundsToClient( g_entities[ i ].client, -price, qtrue ); trap_SendServerCommand( self->client->ps.clientNum, va( "print \"Received ^3%d credits ^7from %s ^7in retribution.\n\"", @@ -447,8 +447,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if ( !toPay[ i ] ) continue; - G_AddCreditToClient( self->client, toPay[ i ], qtrue ); - G_AddCreditToClient( g_entities[ i ].client, -toPay[ i ], qtrue ); + G_AddFundsToClient( self->client, toPay[ i ], qtrue ); + G_AddFundsToClient( g_entities[ i ].client, -toPay[ i ], qtrue ); trap_SendServerCommand( self->client->ps.clientNum, va( "print \"Received ^3%d ^7evos from %s ^7in retribution.\n\"", @@ -533,7 +533,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int percentDamage *= (float)spreeRate; //add credit - G_AddCreditToClient( player->client, + G_AddFundsToClient( player->client, (int)( classValue * percentDamage ), qtrue ); } } @@ -572,9 +572,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int { //add kills if( spreeRate && player == attacker ) - G_AddCreditToClient( player->client, frags * spreeRate, qtrue ); + G_AddFundsToClient( player->client, frags * spreeRate, qtrue ); else - G_AddCreditToClient( player->client, frags, qtrue ); + G_AddFundsToClient( player->client, frags, qtrue ); //can't revist this account later self->credits[ i ] = 0; diff --git a/src/game/g_local.h b/src/game/g_local.h index 708a85a..5250913 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -1124,7 +1124,7 @@ void G_UpdateZaps( int msec ); // // g_client.c // -void G_AddCreditToClient( gclient_t *client, float credit, qboolean cap ); +void G_AddFundsToClient( gclient_t *client, float funds, qboolean cap ); team_t TeamCount( int ignoreClientNum, int team ); void G_SetClientViewAngle( gentity_t *ent, vec3_t angle ); gentity_t *G_SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ); -- cgit