
main(eAttacker, sWeapon, vPoint, aInfo)
{
	self endon("disconnect");

	if(level.ex_lrhitloc && isDefined(aInfo))
	{
		if(isDefined(eAttacker) && isDefined(self))
		{
			if(isDefined(aInfo.sMeansOfDeath) && aInfo.sMeansOfDeath == "MOD_PROJECTILE" && isValidWeapon(sWeapon))
			{
				//logprint("LRHITLOC: passed sMeansOfDeath \"" + aInfo.sMeansOfDeath + "\", sHitLoc \"" + aInfo.sHitLoc + "\", iDamage \"" + aInfo.iDamage + "\"\n");

				rangehm = int(distance(vPoint, self.ex_headmarker.origin));
				rangeem = int(distance(vPoint, self.ex_eyemarker.origin));
				rangesm = int(distance(vPoint, self.ex_spinemarker.origin));
				rangela = int(distance(vPoint, self.ex_lankmarker.origin));
				rangera = int(distance(vPoint, self.ex_rankmarker.origin));
				rangelw = int(distance(vPoint, self.ex_lwristmarker.origin));
				rangerw = int(distance(vPoint, self.ex_rwristmarker.origin));

				if(!isDefined(level.lrhitlocno)) level.lrhitlocno = 0;
				level.lrhitlocno++;
				//logprint("LRHITLOC: hit " + level.lrhitlocno + " distance to hm:" + rangehm + " em:" + rangeem + " sm:" + rangesm + " la:" + rangela + " ra:" + rangera + " lw:" + rangelw + " rw:" + rangerw + "\n");

				aInfo.sMeansOfDeath = "MOD_RIFLE_BULLET";
				aInfo.sHitLoc = "none";
				aInfo.iDamage = 50;

				// Head
				if(rangeem <= 8)
				{
					aInfo.sMeansOfDeath = "MOD_HEAD_SHOT";
					aInfo.sHitLoc = "head";
					aInfo.iDamage = level.ex_lrhitloc_head;
				}
				// Neck
				else if(rangeem > 8 && rangehm <= 5 && rangesm <= 8)
				{
					aInfo.sHitLoc = "neck";
					aInfo.iDamage = level.ex_lrhitloc_neck;
				}
				// Feet
				else if(rangera <= 10 && rangeem > 30)
				{
					aInfo.sHitLoc = "right_foot";
					aInfo.iDamage = level.ex_lrhitloc_right_foot;
				}
				else if(rangela <= 10 && rangeem > 30)
				{
					aInfo.sHitLoc = "left_foot";
					aInfo.iDamage = level.ex_lrhitloc_left_foot;
				}
				// Hands
				else if(rangerw <= 6)
				{
					aInfo.sHitLoc = "right_hand";
					aInfo.iDamage = level.ex_lrhitloc_right_hand;
				}
				else if(rangelw <= 6)
				{
					aInfo.sHitLoc = "left_hand";
					aInfo.iDamage = level.ex_lrhitloc_left_hand;
				}
				// Torso
				else if(rangeem > 6 && rangesm <= 6)
				{
					aInfo.sHitLoc = "torso_upper";
					aInfo.iDamage = level.ex_lrhitloc_torso_upper;
				}
				else if(rangeem > 8 && rangeem < 25 && rangesm > 6 && rangesm <= 18)
				{
					aInfo.sHitLoc = "torso_lower";
					aInfo.iDamage = level.ex_lrhitloc_torso_lower;
				}
				// Legs
				else if(rangeem > 25 && rangera > 10 && rangera < 30)
				{
					aInfo.sHitLoc = "right_leg_upper";
					aInfo.iDamage = level.ex_lrhitloc_right_leg_upper;
				}
				else if(rangeem > 25 && rangera > 1 && rangera < 15)
				{
					aInfo.sHitLoc = "right_leg_lower";
					aInfo.iDamage = level.ex_lrhitloc_right_leg_lower;
				}
				else if(rangeem > 25 && rangela > 10 && rangela < 30)
				{
					aInfo.sHitLoc = "left_leg_upper";
					aInfo.iDamage = level.ex_lrhitloc_left_leg_upper;
				}
				else if(rangeem > 25 && rangela > 1 && rangela < 15)
				{
					aInfo.sHitLoc = "left_leg_lower";
					aInfo.iDamage = level.ex_lrhitloc_left_leg_lower;
				}
				// Arms
				else if(rangesm > 18 && rangerw > 10 && rangerw < 30)
				{
					aInfo.sHitLoc = "right_arm_upper";
					aInfo.iDamage = level.ex_lrhitloc_right_arm_upper;
				}
				else if(rangesm > 18 && rangerw > 1 && rangerw < 15)
				{
					aInfo.sHitLoc = "right_arm_lower";
					aInfo.iDamage = level.ex_lrhitloc_right_arm_lower;
				}
				else if(rangesm > 18 && rangelw > 10 && rangelw < 30)
				{
					aInfo.sHitLoc = "left_arm_upper";
					aInfo.iDamage = level.ex_lrhitloc_left_arm_upper;
				}
				else if(rangesm > 18 && rangelw > 1 && rangelw < 15)
				{
					aInfo.sHitLoc = "left_arm_lower";
					aInfo.iDamage = level.ex_lrhitloc_left_arm_lower;
				}

				if(level.ex_lrhitloc_msg)
				{
					hitloc = getHitlocStringname(aInfo.sHitLoc);
					range = int(distance(eAttacker.origin, self.origin));
					if(level.ex_lrhitloc_unit) rangedist = int(range * 0.02778); // Range in Yards
						else rangedist = int(range * 0.0254); // Range in Metres

					switch(level.ex_lrhitloc_msg)
					{
						case 1:
						{
							if(level.IsLinuxServer) eAttacker iprintln(&"LONGRANGE_HIT", self.name, hitloc);
								else eAttacker iprintln(&"LONGRANGE_HIT", self, hitloc);
							if(level.ex_lrhitloc_unit) eAttacker iprintln(&"OBITUARY_YARDS", rangedist);
								else eAttacker iprintln(&"OBITUARY_METRES", rangedist);
							break;
						}
						case 2:
						{
							if(level.IsLinuxServer) eAttacker iprintlnbold(&"LONGRANGE_HIT", self.name, hitloc);
								else eAttacker iprintlnbold(&"LONGRANGE_HIT", self, hitloc);
							if(level.ex_lrhitloc_unit) eAttacker iprintlnbold(&"OBITUARY_YARDS", rangedist);
								else eAttacker iprintlnbold(&"OBITUARY_METRES", rangedist);
							break;
						}
					}
				}
			}
		}
	}
}

getHitlocStringname(location)
{
	switch(location)
	{
		case "right_hand":      return &"HITLOC_RIGHT_HAND";
		case "left_hand":       return &"HITLOC_LEFT_HAND";
		case "right_arm_upper": return &"HITLOC_RIGHT_UPPER_ARM";
		case "right_arm_lower": return &"HITLOC_RIGHT_FOREARM";
		case "left_arm_upper":  return &"HITLOC_LEFT_UPPER_ARM";
		case "left_arm_lower":  return &"HITLOC_LEFT_FOREARM";
		case "head":            return &"HITLOC_HEAD";
		case "neck":            return &"HITLOC_NECK";
		case "right_foot":      return &"HITLOC_RIGHT_FOOT";
		case "left_foot":       return &"HITLOC_LEFT_FOOT";
		case "right_leg_lower": return &"HITLOC_RIGHT_LOWER_LEG";
		case "left_leg_lower":  return &"HITLOC_LEFT_LOWER_LEG";
		case "right_leg_upper": return &"HITLOC_RIGHT_UPPER_LEG";
		case "left_leg_upper":  return &"HITLOC_LEFT_UPPER_LEG";
		case "torso_upper":     return &"HITLOC_UPPER_TORSO";
		case "torso_lower":     return &"HITLOC_LOWER_TORSO";
		default:                return &"HITLOC_UNKNOWN";
	}
}

isValidWeapon(weapon)
{
	switch(weapon)
	{
		case "springfield_mp":
		case "springfield_2_mp":
		case "enfield_scope_mp":
		case "enfield_scope_2_mp":
		case "mosin_nagant_sniper_mp":
		case "mosin_nagant_sniper_2_mp":
		case "g43_sniper":
		case "g43_sniper_2":
		case "kar98k_sniper_mp":
		case "kar98k_sniper_2_mp": return true;
		default: return false;
	}
}
