void G_PlayerAward( edict_t *ent, const char *awardMsg ) { edict_t *other; char cmd[MAX_STRING_CHARS]; gameaward_t *ga; int i, size; score_stats_t *stats; if( !awardMsg || !awardMsg[0] || !ent->r.client ) return; Q_snprintfz( cmd, sizeof( cmd ), "aw \"%s\"", awardMsg ); trap_GameCmd( ent, cmd ); if( dedicated->integer ) G_Printf( "%s", COM_RemoveColorTokens( va( "%s receives a '%s' award.\n", ent->r.client->netname, awardMsg ) ) ); ent->r.client->level.stats.awards++; teamlist[ent->s.team].stats.awards++; G_Gametype_ScoreEvent( ent->r.client, "award", awardMsg ); stats = &ent->r.client->level.stats; if( !stats->awardAllocator ) stats->awardAllocator = LinearAllocator( sizeof( gameaward_t ), 0, _G_LevelMalloc, _G_LevelFree ); // ch : this doesnt work for race right? if( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH ) { // ch : we store this locally to send to MM // first check if we already have this one on the clients list size = LA_Size( stats->awardAllocator ); ga = NULL; for( i = 0; i < size; i++ ) { ga = ( gameaward_t * )LA_Pointer( stats->awardAllocator, i ); if( !strncmp( ga->name, awardMsg, sizeof(ga->name)-1 ) ) break; } if( i >= size ) { ga = ( gameaward_t * )LA_Alloc( stats->awardAllocator ); memset( ga, 0, sizeof(*ga) ); ga->name = G_RegisterLevelString( awardMsg ); } if( ga ) ga->count++; } // add it to every player who's chasing this player for( other = game.edicts + 1; PLAYERNUM( other ) < gs.maxclients; other++ ) { if( !other->r.client || !other->r.inuse || !other->r.client->resp.chase.active ) continue; if( other->r.client->resp.chase.target == ENTNUM( ent ) ) trap_GameCmd( other, cmd ); } }
// from AS void G_SetRaceTime( edict_t *ent, int sector, unsigned int time ) { gclient_t *cl; raceRun_t *rr; cl = ent->r.client; if( ! ent->r.inuse || cl == NULL ) return; rr = &cl->level.stats.currentRun; if( sector < -1 || sector >= rr->numSectors ) return; // normal sector if( sector >= 0 ) rr->times[sector] = time; else if (rr->numSectors > 0) { raceRun_t *nrr; // new global racerun rr->times[rr->numSectors] = time; rr->timestamp = trap_Milliseconds(); // validate the client // no bots for race, at all if( ent->r.svflags & SVF_FAKECLIENT /* && mm_debug_reportbots->value == 0 */ ) { G_Printf("G_SetRaceTime: not reporting fakeclients\n"); return; } if( cl->mm_session <= 0 ) { G_Printf("G_SetRaceTime: not reporting non-registered clients\n"); return; } if( !game.raceruns ) game.raceruns = LinearAllocator( sizeof( raceRun_t ), 0, _G_LevelMalloc, _G_LevelFree ); // push new run nrr = ( raceRun_t * )LA_Alloc( game.raceruns ); memcpy( nrr, rr, sizeof( raceRun_t ) ); // reuse this one in nrr rr->times = 0; // see if we have to push intermediate result if( LA_Size( game.raceruns ) >= RACERUN_BATCH_SIZE ) { G_Match_SendReport(); // double-check this for memory-leaks if( game.raceruns != 0 ) LinearAllocator_Free( game.raceruns ); game.raceruns = 0; } } }
void G_PlayerMetaAward( edict_t *ent, const char *awardMsg ) { int i, size; gameaward_t *ga; score_stats_t *stats; /* * ch : meta-award is an award that isn't announced but * it is sent to MM */ if( !awardMsg || !awardMsg[0] || !ent->r.client ) return; stats = &ent->r.client->level.stats; if( !stats->awardAllocator ) stats->awardAllocator = LinearAllocator( sizeof( gameaward_t ), 0, _G_LevelMalloc, _G_LevelFree ); // ch : this doesnt work for race right? if( GS_MatchState() == MATCH_STATE_PLAYTIME ) { // ch : we store this locally to send to MM // first check if we already have this one on the clients list size = LA_Size( stats->awardAllocator ); ga = NULL; for( i = 0; i < size; i++ ) { ga = LA_Pointer( stats->awardAllocator, i ); if( !strncmp( ga->name, awardMsg, sizeof(ga->name)-1 ) ) break; } if( i >= size ) { ga = LA_Alloc( stats->awardAllocator ); memset( ga, 0, sizeof(*ga) ); ga->name = G_RegisterLevelString( awardMsg ); } if( ga ) ga->count++; } }
void G_AwardPlayerKilled( edict_t *self, edict_t *inflictor, edict_t *attacker, int mod ) { trace_t trace; score_stats_t *stats; loggedFrag_t *lfrag; if( self->r.svflags & SVF_CORPSE ) return; if( !attacker->r.client ) return; if( !self->r.client ) return; if( attacker == self ) return; if( attacker->s.team == self->s.team && attacker->s.team > TEAM_PLAYERS ) return; if( mod == MOD_ROCKET_W || mod == MOD_ROCKET_S ) { // direct hit attacker->r.client->resp.awardInfo.directrocket_count++; if( attacker->r.client->resp.awardInfo.directrocket_count == DIRECTROCKET_FOR_AWARD ) { attacker->r.client->resp.awardInfo.directrocket_count = 0; attacker->r.client->resp.awardInfo.directrocket_award++; G_PlayerAward( attacker, S_COLOR_BLUE "Direct Rocket Hit!" ); } // Midair if( self->groundentity == NULL && !self->waterlevel ) { // check for height to the ground G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID ); if( trace.fraction == 1.0f ) { attacker->r.client->resp.awardInfo.rl_midair_award++; G_PlayerAward( attacker, S_COLOR_BLUE "Air Rocket!" ); } } } if( mod == MOD_GRENADE_W || mod == MOD_GRENADE_S ) { // direct hit attacker->r.client->resp.awardInfo.directgrenade_count++; if( attacker->r.client->resp.awardInfo.directgrenade_count == DIRECTGRENADE_FOR_AWARD ) { attacker->r.client->resp.awardInfo.directgrenade_count = 0; attacker->r.client->resp.awardInfo.directgrenade_award++; G_PlayerAward( attacker, S_COLOR_BLUE "Direct Grenade Hit!" ); } // Midair if( self->groundentity == NULL && !self->waterlevel ) { // check for height to the ground G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID ); if( trace.fraction == 1.0f ) { attacker->r.client->resp.awardInfo.gl_midair_award++; G_PlayerAward( attacker, S_COLOR_BLUE "Air Grenade!" ); } } } // Multikill if( game.serverTime - attacker->r.client->resp.awardInfo.multifrag_timer < MULTIKILL_INTERVAL ) attacker->r.client->resp.awardInfo.multifrag_count++; else attacker->r.client->resp.awardInfo.multifrag_count = 1; attacker->r.client->resp.awardInfo.multifrag_timer = game.serverTime; if( attacker->r.client->resp.awardInfo.multifrag_count > 1 ) { char s[MAX_CONFIGSTRING_CHARS]; s[0] = 0; switch( attacker->r.client->resp.awardInfo.multifrag_count ) { case 0: case 1: break; case 2: Q_strncpyz( s, S_COLOR_GREEN "Double Frag!", sizeof( s ) ); break; case 3: Q_strncpyz( s, S_COLOR_GREEN "Triple Frag!", sizeof( s ) ); break; case 4: Q_strncpyz( s, S_COLOR_GREEN "Quadruple Frag!", sizeof( s ) ); break; default: Q_snprintfz( s, sizeof( s ), S_COLOR_GREEN "Extermination! %i in a row!", attacker->r.client->resp.awardInfo.multifrag_count ); break; } G_PlayerAward( attacker, s ); } // Sprees attacker->r.client->resp.awardInfo.frag_count++; if( attacker->r.client->resp.awardInfo.frag_count && ( attacker->r.client->resp.awardInfo.frag_count % 5 == 0 ) ) { char s[MAX_CONFIGSTRING_CHARS]; s[0] = 0; switch( (int)( attacker->r.client->resp.awardInfo.frag_count / 5 ) ) { case 1: Q_strncpyz( s, S_COLOR_YELLOW "On Fire!", sizeof( s ) ); G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is On Fire!\n", attacker->r.client->netname ); break; case 2: Q_strncpyz( s, S_COLOR_YELLOW "Raging!", sizeof( s ) ); G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Raging!\n", attacker->r.client->netname ); break; case 3: Q_strncpyz( s, S_COLOR_YELLOW "Fraglord!", sizeof( s ) ); G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is the Fraglord!\n", attacker->r.client->netname ); break; case 4: Q_strncpyz( s, S_COLOR_YELLOW "Extermination!", sizeof( s ) ); G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Exterminating!\n", attacker->r.client->netname ); break; default: Q_strncpyz( s, S_COLOR_YELLOW "God Mode!", sizeof( s ) ); G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is in God Mode!\n", attacker->r.client->netname ); break; } G_PlayerAward( attacker, s ); } // ch : weapon specific frags if ( G_ModToAmmo( mod ) != AMMO_NONE ) attacker->r.client->level.stats.accuracy_frags[G_ModToAmmo( mod )-AMMO_GUNBLADE]++; if( GS_MatchState() == MATCH_STATE_PLAYTIME /* && !strcmp( "duel", gs.gametypeName ) */) { // ch : frag log stats = &attacker->r.client->level.stats; if( !stats->fragAllocator ) stats->fragAllocator = LinearAllocator( sizeof( loggedFrag_t ), 0, _G_LevelMalloc, _G_LevelFree ); lfrag = LA_Alloc( stats->fragAllocator ); lfrag->mm_attacker = attacker->r.client->mm_session; lfrag->mm_victim = self->r.client->mm_session; lfrag->weapon = G_ModToAmmo( mod ) - AMMO_GUNBLADE; lfrag->time = ( game.serverTime - GS_MatchStartTime() ) / 1000; } }