Esempio n. 1
0
// Records weapon headshots
void G_addStatsHeadShot(gentity_t *attacker, int mod)
{
#ifndef DEBUG_STATS
	if(g_gamestate.integer != GS_PLAYING) {
		return;
	}
#endif
	if(!attacker || !attacker->client) return;

	attacker->client->sess.aWeaponStats[G_weapStatIndex_MOD(mod)].headshots++;
}
Esempio n. 2
0
// Records accuracy, damage, and kill/death stats.
void G_addStats(gentity_t *targ, gentity_t *attacker, int dmg_ref, int mod)
{
	int dmg, ref;

	if (!targ || !targ->client)
	{
		return;
	}

	// Keep track of only active player-to-player interactions in a real game
	if (
#ifndef DEBUG_STATS
	    g_gamestate.integer != GS_PLAYING ||
#endif
	    mod == MOD_SWITCHTEAM ||
	    (g_gametype.integer >= GT_WOLF && (targ->client->ps.pm_flags & PMF_LIMBO)) || // FIXME: inspect - this is a bit odd by gametype
	    (g_gametype.integer < GT_WOLF && (targ->s.eFlags == EF_DEAD || targ->client->ps.pm_type == PM_DEAD)))
	{
		return;
	}

	// Special hack for intentional gibbage
	if (targ->health <= 0 && targ->client->ps.pm_type == PM_DEAD)
	{
		if (attacker && attacker->client)
		{
			int x;

			ref = G_weapStatIndex_MOD(mod);
			x   = attacker->client->sess.aWeaponStats[ref].atts--;

			if (x < 1)
			{
				attacker->client->sess.aWeaponStats[ref].atts = 1;
			}
		}
		return;
	}

	//  G_Printf("mod: %d, Index: %d, dmg: %d\n", mod, G_weapStatIndex_MOD(mod), dmg_ref);

	// Selfkills only affect the player specifically
	if (targ == attacker || !attacker || !attacker->client || mod == MOD_SUICIDE) // FIXME: inspect world kills count as selfkill?
	{
		if (targ->health <= 0)
		{
			targ->client->sess.selfkills++;
		}
#ifdef DEBUG_STATS
		if (!attacker || !attacker->client)
#endif
		return;
	}

	// Telefrags only add 100 points.. not 100k!!
	if (mod == MOD_TELEFRAG)
	{
		dmg = 100;
	}
	else
	{
		dmg = dmg_ref;
	}

	// Player team stats
	if (g_gametype.integer >= GT_WOLF &&
	    targ->client->sess.sessionTeam == attacker->client->sess.sessionTeam)
	{
		attacker->client->sess.team_damage_given += dmg;
		targ->client->sess.team_damage_received  += dmg;
		if (targ->health <= 0)
		{
			attacker->client->sess.team_kills++;
		}
#ifndef DEBUG_STATS
		return;
#endif
	}

	// General player stats
	if (mod != MOD_SYRINGE)
	{
		attacker->client->sess.damage_given += dmg;
		targ->client->sess.damage_received  += dmg;
		if (targ->health <= 0)
		{
			attacker->client->sess.kills++;
			targ->client->sess.deaths++;
		}
	}

	// Player weapon stats
	ref = G_weapStatIndex_MOD(mod);
	if (dmg > 0)
	{
		attacker->client->sess.aWeaponStats[ref].hits++;
	}
	if (targ->health <= 0)
	{
		attacker->client->sess.aWeaponStats[ref].kills++;
		targ->client->sess.aWeaponStats[ref].deaths++;
	}
}
Esempio n. 3
0
// Records accuracy, damage, and kill/death stats.
void G_addStats(gentity_t *targ, gentity_t *attacker, int dmg_ref, int mod)
{
	int dmg, ref;
	//forty - #349 - Moved this to the end of ClientEndFrame to prevent invisible clips from forming.
	//float teamHitPct = 0;
	//int banTime = 0;
	qboolean onSameTeam;
	int limbo_health = FORCE_LIMBO_HEALTH;

	/*
	// Keep track of only active player-to-player interactions in a real game
	if(!targ || !targ->client ||
#ifndef DEBUG_STATS
	  g_gamestate.integer != GS_PLAYING ||
#endif
	  mod == MOD_SWITCHTEAM ||
	  (g_gametype.integer >= GT_WOLF && (targ->client->ps.pm_flags & PMF_LIMBO)) || 
	  (g_gametype.integer < GT_WOLF && (targ->s.eFlags == EF_DEAD || targ->client->ps.pm_type == PM_DEAD))) {
		return;
	}
	*/

	if(!targ || !targ->client) 
		return;

	// Special hack for intentional gibbage
	if(targ->health <= 0 && targ->client->ps.pm_type == PM_DEAD) {

		// tjw: I'm not sure what the mod check is for, but it was
		//      in the original etmain, so I'm leaving it.
		if((g_stats.integer & STATF_CORPSE_NO_SHOT) &&
			mod < MOD_CROSS && attacker && attacker->client) {

			int idx = G_weapStatIndex_MOD(mod);
			int x;

			x = attacker->client->sess.aWeaponStats[idx].atts--;
			if(x < 1)
				attacker->client->sess.aWeaponStats[idx].atts = 1;
		}
		if(g_stats.integer & STATF_CORPSE_NO_HIT) {
			return;
		}
	}

	if(g_gamestate.integer != GS_PLAYING)
		return;

	if(mod == MOD_SWITCHTEAM) 
		return;

	if((targ->client->ps.pm_flags & PMF_LIMBO))
		return;

	if((targ->client->ps.eFlags & EF_DEAD) &&
		!(targ->client->ps.eFlags & EF_PLAYDEAD) &&
		attacker->client) {

		attacker->client->sess.aWeaponStats[G_weapStatIndex_MOD(mod)].hits++;
		return;
	}

//	G_Printf("mod: %d, Index: %d, dmg: %d\n", mod, G_weapStatIndex_MOD(mod), dmg_ref);

	// Suicides only affect the player specifically
	if(targ == attacker || !attacker || !attacker->client || mod == MOD_SUICIDE) {
		if(targ->health <= 0) targ->client->sess.suicides++;
#ifdef DEBUG_STATS
		if(!attacker || !attacker->client)
#endif
			return;
	}

	// Telefrags only add 100 points.. not 100k!!
	if(mod == MOD_TELEFRAG) dmg = 100;
	else dmg = dmg_ref;

	// tjw: you can't do more damage than the victim has to give
	if(g_forceLimboHealth.integer == 1)
			limbo_health = FORCE_LIMBO_HEALTH2;

	//G_Printf("Damage before : %d\n", dmg);
	//G_Printf("targ->health : %d\n", targ->health);
	//G_Printf("limbo_health : %d\n", limbo_health);

	if(targ->health > 0) {
		if(dmg > (targ->health + abs(limbo_health)))
			dmg = (targ->health + abs(limbo_health));
	} else {
		/* - forty this gives negative damage stats.
		if(dmg > (abs(limbo_health) - abs(targ->health)))
			dmg = (abs(limbo_health) - abs(targ->health));
		*/

		// forty - I guess don't let them add up more than gib health with a single shot.
		//		   since we don't know what the health was at before the add-stats.
        if(dmg > abs(GIB_HEALTH)) 
			dmg = abs(GIB_HEALTH);
	}

	//G_Printf("Damage after : %d\n", dmg);

	// Player team stats
/*	if(g_gametype.integer >= GT_WOLF &&
	  targ->client->sess.sessionTeam == attacker->client->sess.sessionTeam) {
		attacker->client->sess.team_damage += dmg;
		if(targ->health <= 0) attacker->client->sess.team_kills++;
#ifndef DEBUG_STATS
		return;
#endif
	}*/

	if(g_gametype.integer < GT_WOLF)
		return;

	onSameTeam = 
		targ->client->sess.sessionTeam == 
			attacker->client->sess.sessionTeam;

	// forty - #607 - Merge in Density's damage received display code
	if( onSameTeam ) {
		switch(mod) {
			case MOD_SYRINGE:
				break;
			case MOD_FLAMETHROWER:
				attacker->client->sess.team_damage_given += dmg;
				targ->client->sess.team_damage_received += dmg;
				attacker->client->sess.team_hits += 0.1f;
				attacker->client->sess.hits += 0.1f;
				break;
			case MOD_LANDMINE:
				attacker->client->sess.team_damage_given += dmg;
				targ->client->sess.team_damage_received += dmg;
				attacker->client->sess.team_hits += 0.5f;
				attacker->client->sess.hits += 0.5f;
				break;
			default:
				attacker->client->sess.team_damage_given += dmg;
				targ->client->sess.team_damage_received += dmg;
				attacker->client->sess.team_hits++;
				attacker->client->sess.hits++;
		}
		if(targ->health <= 0)
			attacker->client->sess.team_kills++;
	} else {
		attacker->client->sess.damage_given += dmg;
		switch(mod) {
			case MOD_POISON:
				// only count initial syringe hit
				// not subsequent MOD_POISON G_Damage calls
				if(!targ->client->pmext.poisoned) {
					attacker->client->sess.hits++;
				}
				break;
			case MOD_FLAMETHROWER:
				attacker->client->sess.hits += 0.1f;
				break;
			default:
				attacker->client->sess.hits++;
		}
		targ->client->sess.damage_received += dmg;
		if(targ->health <= 0) {
			attacker->client->sess.kills++;
			targ->client->sess.deaths++;
			// josh: track kill rating with enhanced glicko 
			if (g_killRating.integer) {
				G_UpdateKillRatings(attacker,targ,mod);
			}
			if (g_killRating.integer & KILL_RATING_DATASET) {
				G_LogKillGUID(attacker,targ,mod);
			}
		}
	}

	// General player stats
/*	if(mod != MOD_SYRINGE && 
			targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam) {
		attacker->client->sess.damage_given += dmg;
		targ->client->sess.damage_received += dmg;
		if(targ->health <= 0) {
			attacker->client->sess.kills++;
			targ->client->sess.deaths++;
		}
*/
	// Player weapon stats
	ref = G_weapStatIndex_MOD(mod);
	// tjw: only record syringe hits for the initial hit
	if(dmg > 0 && !targ->client->pmext.poisoned)
		attacker->client->sess.aWeaponStats[ref].hits++;
	// matt: strict shrub implementation doesn't count weapon kills/deaths
	// if done to a teammate
	if(targ->health <= 0 && !onSameTeam) {
		attacker->client->sess.aWeaponStats[ref].kills++;
		targ->client->sess.aWeaponStats[ref].deaths++;
	}

	/* forty - #349 - Moved this to the end of ClientEndFrame to prevent invisible clips from forming.
	if ( g_teamDamageRestriction.integer > 0 && 
			!G_shrubbot_permission(attacker, SBF_IMMUNITY)) {
		if ( attacker->client->sess.hits > 0 )
			teamHitPct = (attacker->client->sess.team_hits / 
					attacker->client->sess.hits)*(100);
		if ( attacker->client->sess.hits >= g_minHits.integer && 
				teamHitPct > g_teamDamageRestriction.integer ) {
			if ( g_autoTempBan.integer && 
					g_autoTempBanTime.integer )
				banTime = g_autoTempBanTime.integer;
			// reset team_hits and hits to avoid 
			// vicious kick/rejoin/kick cycle
			attacker->client->sess.team_hits = 0.f;
			attacker->client->sess.hits = 0.f;

			// forty - enforce the temp ban consistently using shrubbot. 
			if(banTime)
				G_shrubbot_tempban(attacker-g_entities,"Temporarily banned - Stop team killing!", banTime);
			trap_DropClient(attacker-g_entities,
					va("Kicked for %d seconds for"
						" excessive team damage",
						banTime),banTime);
		}
	}
	*/
}