void CGEStats::Event_PlayerDamage( CBasePlayer *pBasePlayer, const CTakeDamageInfo &info )
{
	//Make sure there is a player taking the damage
	if( !pBasePlayer )
		return;
	int iVictim = FindPlayer( pBasePlayer );
	
	CBasePlayer* pAttacker = static_cast<CBasePlayer*>(info.GetAttacker());
	if( !pAttacker->IsPlayer() )
		return;
	int iAttacker = FindPlayer( pAttacker );

	// We hurt ourselves...
	if ( iAttacker == iVictim )
	{
		m_pPlayerStats[iVictim]->AddStat( GE_AWARD_PROFESSIONAL, -2);
		m_pPlayerStats[iVictim]->AddStat( GE_AWARD_LEMMING, 1 );
		return;
	}

	// Add the inflicted damage to our Most Deadly stat
	m_pPlayerStats[iAttacker]->AddStat( GE_AWARD_DEADLY, info.GetDamage() );
	// Add to the victim's mostly harmless award 1/2 the damage
	m_pPlayerStats[iVictim]->AddStat( GE_AWARD_MOSTLYHARMLESS, info.GetDamage() / 2 );

	// See where this attack hit and then apply appropriate marksmanship points
	int points = 0;
	switch ( pBasePlayer->LastHitGroup() )
	{
		case HITGROUP_HEAD:
			points = 5; break;

		case HITGROUP_CHEST:
		case HITGROUP_STOMACH: 
			points = 3; break;

		case HITGROUP_LEFTARM:
		case HITGROUP_RIGHTARM:
		case HITGROUP_LEFTLEG:
		case HITGROUP_RIGHTLEG:
			points = 1; break;
	}

	m_pPlayerStats[iAttacker]->AddStat( GE_AWARD_MARKSMANSHIP, points );

	// test if its fall damage
	if( !info.GetInflictor() )
	{
		m_pPlayerStats[iVictim]->AddStat( GE_AWARD_PROFESSIONAL, -2);
		return;
	}

	// Find out what weapons we are using
	CGEWeapon *pVicWeapon = static_cast<CGEWeapon*>(pBasePlayer->GetActiveWeapon());
	CGEWeapon *pWeapon = NULL;

	if ( info.GetInflictor() == pAttacker )
		pWeapon = static_cast<CGEWeapon*>(pAttacker->GetActiveWeapon());
	else
		pWeapon = dynamic_cast<CGEWeapon*>(info.GetInflictor());

	// If the victim reports no weapon, or our victim wasn't killed by a GEWeapon, then break
	if ( !pWeapon || !pVicWeapon )
		return;

	// Don't give honor to mine kills as it doesn't make a difference
	if ( pWeapon->GetWeaponID() < WEAPON_TIMEDMINE || pWeapon->GetWeaponID() > WEAPON_GRENADE )
	{
		// Define variables to find honor
		Vector vecVic, vecToAtt, right;

		// Get the victim's forward normal, their position, and the attacker's position
		pBasePlayer->EyeVectors( &vecVic, &right );
		vecVic.NormalizeInPlace();

		// Use vector subtration to find a vector to the attacker FROM the victim
		vecToAtt = pAttacker->EyePosition() - pBasePlayer->EyePosition();
		vecToAtt.NormalizeInPlace();
		
		// Find the angle between the two vectors
		float front = DotProduct(vecToAtt, vecVic);
		float side = DotProduct(vecToAtt, right);
		float xpos = 360.0f * -side;
		float ypos = 360.0f * -front;

		// Get the rotation (yaw)
		float ang = abs( atan2(xpos, ypos) );
		float scale;

		if ( ang > 2.10f ) {
			scale = RemapValClamped( ang, 2.10f, 3.14f, 0.2f, 1.0f );
			m_pPlayerStats[iAttacker]->AddStat( GE_AWARD_HONORABLE, 10*scale );
		} else if ( ang < 1.05f ) {
			scale = RemapValClamped( ang, 0.0f, 1.05f, 0.2f, 1.0f );
			m_pPlayerStats[iAttacker]->AddStat( GE_AWARD_DISHONORABLE, 10*scale );
		}
	}

	//Attacker using slappers, Victim not
	if( pWeapon->GetWeaponID() == WEAPON_SLAPPERS && pVicWeapon->GetWeaponID() != WEAPON_SLAPPERS )
	{
		m_pPlayerStats[iAttacker]->AddStat(GE_AWARD_DEADLY, 10);
		m_pPlayerStats[iAttacker]->AddStat(GE_AWARD_HONORABLE, 10);
	}
	
	//Victim using slappers, Attacker not
	if( pWeapon->GetWeaponID() != WEAPON_SLAPPERS && pVicWeapon->GetWeaponID() == WEAPON_SLAPPERS )
	{
		m_pPlayerStats[iAttacker]->AddStat(GE_AWARD_DISHONORABLE, 10);
		m_pPlayerStats[iAttacker]->AddStat(GE_AWARD_PROFESSIONAL, -5);
	}

	BaseClass::Event_PlayerDamage( pBasePlayer, info );
}
Esempio n. 2
0
/* add or subtract something to/from a list */
int list_addsub(int p, char* list, char* who, int addsub)
{
  struct player *pp = &player_globals.parray[p];
  int p1, connected, loadme, personal, ch;
  char *listname, *member, junkChar;
  struct List *gl;
  char *yourthe, *addrem;

  gl = list_findpartial(p, list, addsub);
  if (!gl)
    return COM_OK;

  personal = ListArray[gl->which].rights == P_PERSONAL;
  loadme = (gl->which != L_FILTER) && (gl->which != L_REMOVEDCOM) && (gl->which != L_CHANNEL);
  listname = ListArray[gl->which].name;
  yourthe = personal ? "your" : "the";
  addrem = (addsub == 1) ? "added to" : "removed from";

  if (loadme) {
    if (!FindPlayer(p, who, &p1, &connected)) {
      if (addsub == 1)
        return COM_OK;
      member = who;		/* allow sub removed/renamed player */
      loadme = 0;
    } else
      member = player_globals.parray[p1].name;
  } else {
    member = who;
  }

  if (addsub == 1) {		/* add to list */

   if (gl->which == L_CHANNEL) {

     if (sscanf (who,"%d%c",&ch, &junkChar) == 1 && ch >= 0 && ch < 255) {
       if ((ch == 0) && (!in_list(p,L_ADMIN,pp->name))) {
         pprintf(p, "Only admins may join channel 0.\n");
         return COM_OK;
       }
     } else {
         pprintf (p,"The channel to add must be a number between 0 and %d.\n",MAX_CHANNELS - 1);
         return COM_OK;
  	}
  }
  if (in_list(p, gl->which, member)) {
     pprintf(p, "[%s] is already on %s %s list.\n", member, yourthe, listname);
     if (loadme && !connected)
       player_remove(p1);
     return COM_OK;
    }
    if (list_add(p, gl->which, member)) {
      pprintf(p, "Sorry, %s %s list is full.\n", yourthe, listname);
      if (loadme && !connected)
	player_remove(p1);
      return COM_OK;
    }
  } else if (addsub == 2) {	/* subtract from list */
    if (!in_list(p, gl->which, member)) {
      pprintf(p, "[%s] is not in %s %s list.\n", member, yourthe, listname);
      if (loadme && !connected)
	player_remove(p1);
      return COM_OK;
    }
    list_sub(p, gl->which, member);
  }
  pprintf(p, "[%s] %s %s %s list.\n", member, addrem, yourthe, listname);

  if (!personal) {
    FILE *fp;
    char filename[MAX_FILENAME_SIZE];

    switch (gl->which) {
    case L_MUZZLE:
    case L_CMUZZLE:
    case L_C1MUZZLE:
    case L_C24MUZZLE:
    case L_C46MUZZLE:
    case L_C49MUZZLE:
    case L_C50MUZZLE:
    case L_C51MUZZLE:
    case L_ABUSER:
    case L_BAN:
    case L_NOTEBAN:
    case L_RATEBAN:
      pprintf(p, "Please leave a comment to explain why %s was %s the %s list.\n", member, addrem, listname);
      pcommand(p, "addcomment %s %s %s list.\n", member, addrem, listname);
      break;
    case L_COMPUTER:
      /*if (player_globals.parray[p1].z_stats.rating > 0)
	UpdateRank(TYPE_CRAZYHOUSE, member, &player_globals.parray[p1].z_stats, member);
      if (player_globals.parray[p1].s_stats.rating > 0)
	UpdateRank(TYPE_STAND, member, &player_globals.parray[p1].s_stats, member);
      if (player_globals.parray[p1].w_stats.rating > 0)
	UpdateRank(TYPE_WILD, member, &player_globals.parray[p1].w_stats, member);*/
      break;
    case L_ADMIN:
      if (addsub == 1) {	/* adding to list */
	player_globals.parray[p1].adminLevel = 10;
	pprintf(p, "%s has been given an admin level of 10 - change with asetadmin.\n", member);
      } else {
	player_globals.parray[p1].adminLevel = 0;
      }
      break;
    case L_FILTER:
    case L_REMOVEDCOM:
    default:
      break;
    }

    if (loadme && connected)
        pprintf_prompt(p1, "You have been %s the %s list by %s.\n",
                                    addrem, listname, pp->name);

    sprintf(filename, "%s/%s", LISTS_DIR, listname);
    fp = fopen_s(filename, "w");
    if (fp == NULL) {
      d_printf( "Couldn't save %s list.\n", listname);
    } else {
      int i;
      for (i = 0; i < gl->numMembers; i++)
	fprintf(fp, "%s\n", gl->m_member[i]);
      fclose(fp);
    }
  }
  if (loadme || (gl->which == L_ADMIN)) {
    player_save(p1);
  }
  if (loadme && !connected) {
    player_remove(p1);
  }
  return COM_OK;
}