code:
/*
Contains most of the procs that are called when a mob is attacked by something

bullet_act
emp_act
*/

/mob/living/carbon/human/getarmor(var/def_zone, var/type)
	var/armorval = 0
	var/organnum = 0

	if(def_zone)
		if(isorgan(def_zone))
			return checkarmor(def_zone, type)
		var/obj/item/organ/limb/affecting = get_organ(ran_zone(def_zone))
		return checkarmor(affecting, type)
		//If a specific bodypart is targetted, check how that bodypart is protected and return the value.

	//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
	for(var/obj/item/organ/limb/organ in organs)
		armorval += checkarmor(organ, type)
		organnum++
	return (armorval/max(organnum, 1))

/mob/living/carbon/human/proc/checkarmor(var/obj/item/organ/limb/def_zone, var/type)
	if(!type)	return 0
	var/protection = 0
	var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
	for(var/bp in body_parts)
		if(!bp)	continue
		if(bp && istype(bp ,/obj/item/clothing))
			var/obj/item/clothing/C = bp
			if(C.body_parts_covered & def_zone.body_part)
				protection += C.armor[type]
	return protection

/mob/living/carbon/human/on_hit(proj_type)
	if(dna)
		dna.species.on_hit(proj_type, src)
	return

/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
	if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
		if(check_reflect(def_zone)) // Checks if you've passed a reflection% check
			visible_message("The [P.name] gets reflected by [src]!", \
							"The [P.name] gets reflected by [src]!")
			// Find a turf near or on the original location to bounce to
			if(P.starting)
				var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
				var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
				var/turf/curloc = get_turf(src)

				// redirect the projectile
				P.original = locate(new_x, new_y, P.z)
				P.starting = curloc
				P.current = curloc
				P.firer = src
				P.yo = new_y - curloc.y
				P.xo = new_x - curloc.x

			return -1 // complete projectile permutation

	if(check_shields(P.damage, "the [P.name]"))
		P.on_hit(src, 100, def_zone)
		return 2
	return (..(P , def_zone))

/mob/living/carbon/human/proc/check_reflect(var/def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object
	if(wear_suit && istype(wear_suit, /obj/item/))
		var/obj/item/I = wear_suit
		if(I.IsReflect(def_zone) == 1)
			return 1
	if(l_hand && istype(l_hand, /obj/item/))
		var/obj/item/I = l_hand
		if(I.IsReflect(def_zone) == 1)
			return 1
	if(r_hand && istype(r_hand, /obj/item/))
		var/obj/item/I = r_hand
		if(I.IsReflect(def_zone) == 1)
			return 1
	return 0

//End Here

/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
	if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
		var/obj/item/weapon/I = l_hand
		if(I.IsShield() && (prob(50 - round(damage / 3))))
			visible_message("[src] blocks [attack_text] with [l_hand]!", \
							"[src] blocks [attack_text] with [l_hand]!")
			return 1
	if(r_hand && istype(r_hand, /obj/item/weapon))
		var/obj/item/weapon/I = r_hand
		if(I.IsShield() && (prob(50 - round(damage / 3))))
			visible_message("[src] blocks [attack_text] with [r_hand]!", \
							"[src] blocks [attack_text] with [r_hand]!")
			return 1
	if(wear_suit && istype(wear_suit, /obj/item/))
		var/obj/item/I = wear_suit
		if(I.IsShield() && (prob(35)))
			visible_message("The reactive teleport system flings [src] clear of [attack_text]!", \
							"The reactive teleport system flings [src] clear of [attack_text]!")
			var/list/turfs = new/list()
			for(var/turf/T in orange(6))
				if(istype(T,/turf/space)) continue
				if(T.density) continue
				if(T.x>world.maxx-6 || T.x<6)	continue
				if(T.y>world.maxy-6 || T.y<6)	continue
				turfs += T
			if(!turfs.len) turfs += pick(/turf in orange(6))
			var/turf/picked = pick(turfs)
			if(!isturf(picked)) return
			if(buckled)
				buckled.unbuckle_mob()
			src.loc = picked
			return 1
	return 0

/mob/living/carbon/human/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone)
	if(!I || !user)	return 0

	var/obj/item/organ/limb/target_limb = get_organ(check_zone(user.zone_sel.selecting))
	var/obj/item/organ/limb/affecting = get_organ(ran_zone(user.zone_sel.selecting))
	var/hit_area = parse_zone(affecting.name)
	var/target_area = parse_zone(target_limb.name)

	if(dna)	// allows your species to affect the attacked_by code
		return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src)

	else
		if(user != src)
			user.do_attack_animation(src)
			if(check_shields(I.force, "the [I.name]"))
				return 0

		if(I.attack_verb && I.attack_verb.len)
			visible_message("[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!", \
							"[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!")
		else if(I.force)
			visible_message("[user] has attacked [src] in the [hit_area] with [I]!", \
							"[user] has attacked [src] in the [hit_area] with [I]!")
		else
			return 0

		var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].")
		if(armor >= 100)	return 0
		var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)

		apply_damage(I.force, I.damtype, affecting, armor , I)

		var/bloody = 0
		if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
			if(affecting.status == ORGAN_ORGANIC)
				I.add_blood(src)	//Make the weapon bloody, not the person.
				if(prob(I.force * 2))	//blood spatter!
					bloody = 1
					var/turf/location = loc
					if(istype(location, /turf/simulated))
						location.add_blood(src)
					if(ishuman(user))
						var/mob/living/carbon/human/H = user
						if(get_dist(H, src) <= 1)	//people with TK won't get smeared with blood
							if(H.wear_suit)
								H.wear_suit.add_blood(src)
								H.update_inv_wear_suit(0)	//updates mob overlays to show the new blood (no refresh)
							else if(H.w_uniform)
								H.w_uniform.add_blood(src)
								H.update_inv_w_uniform(0)	//updates mob overlays to show the new blood (no refresh)
							if (H.gloves)
								var/obj/item/clothing/gloves/G = H.gloves
								G.add_blood(H)
							else
								H.add_blood(H)
								H.update_inv_gloves()	//updates on-mob overlays for bloody hands and/or bloody gloves

			switch(hit_area)
				if("head")	//Harder to score a stun but if you do it lasts a bit longer
					if(stat == CONSCIOUS)
						if(prob(I.force))
							visible_message("[src] has been knocked unconscious!", \
											"[src] has been knocked unconscious!")
							apply_effect(20, PARALYZE, armor)
						if(prob(I.force + ((100 - src.health)/2)) && src != user && I.damtype == BRUTE)
							ticker.mode.remove_revolutionary(mind)
							ticker.mode.remove_gangster(mind, exclude_bosses=1)
					if(bloody)	//Apply blood
						if(wear_mask)
							wear_mask.add_blood(src)
							update_inv_wear_mask(0)
						if(head)
							head.add_blood(src)
							update_inv_head(0)
						if(glasses && prob(33))
							glasses.add_blood(src)
							update_inv_glasses(0)

				if("chest")	//Easier to score a stun but lasts less time
					if(stat == CONSCIOUS && I.force && prob(I.force + 10))
						visible_message("[src] has been knocked down!", \
										"[src] has been knocked down!")
						apply_effect(5, WEAKEN, armor)

					if(bloody)
						if(wear_suit)
							wear_suit.add_blood(src)
							update_inv_wear_suit(0)
						if(w_uniform)
							w_uniform.add_blood(src)
							update_inv_w_uniform(0)

			if(Iforce > 10 || Iforce >= 5 && prob(33))
				forcesay(hit_appends)	//forcesay checks stat already

/mob/living/carbon/human/emp_act(severity)
	var/informed = 0
	for(var/obj/item/organ/limb/L in src.organs)
		if(L.status == ORGAN_ROBOTIC)
			if(!informed)
				src << "You feel a sharp pain as your robotic limbs overload."
				informed = 1
			switch(severity)
				if(1)
					L.take_damage(0,10)
					src.Stun(10)
				if(2)
					L.take_damage(0,5)
					src.Stun(5)
	..()

/mob/living/carbon/human/acid_act(var/acidpwr, var/toxpwr, var/acid_volume)
	var/list/damaged = list()
	var/list/inventory_items_to_kill = list()

	//HEAD//
	var/obj/item/clothing/head_clothes = null
	if(glasses)
		head_clothes = glasses
	if(wear_mask)
		head_clothes = wear_mask
	if(head)
		head_clothes = head
	if(head_clothes)
		if(!head_clothes.unacidable)
			head_clothes.acid_act(acidpwr)
			update_inv_glasses()
			update_inv_wear_mask()
			update_inv_head()
		else
			src << "Your [head_clothes.name] protects your head and face from the acid!"
	else
		. = get_organ("head")
		if(.)
			damaged += .
		if(ears)
			inventory_items_to_kill += ears

	//CHEST//
	var/obj/item/clothing/chest_clothes = null
	if(w_uniform)
		chest_clothes = w_uniform
	if(wear_suit)
		chest_clothes = wear_suit
	if(chest_clothes)
		if(!chest_clothes.unacidable)
			chest_clothes.acid_act(acidpwr)
			update_inv_w_uniform()
			update_inv_wear_suit()
		else
			src << "Your [chest_clothes.name] protects your body from the acid!"
	else
		. = get_organ("chest")
		if(.)
			damaged += .
		if(wear_id)
			inventory_items_to_kill += wear_id
		if(r_store)
			inventory_items_to_kill += r_store
		if(l_store)
			inventory_items_to_kill += l_store
		if(s_store)
			inventory_items_to_kill += s_store

	//ARMS & HANDS//
	var/obj/item/clothing/arm_clothes = null
	if(gloves)
		arm_clothes = gloves
	if(w_uniform && (w_uniform.body_parts_covered & HANDS) || w_uniform && (w_uniform.body_parts_covered & ARMS))
		arm_clothes = w_uniform
	if(wear_suit && (wear_suit.body_parts_covered & HANDS) || wear_suit && (wear_suit.body_parts_covered & ARMS))
		arm_clothes = wear_suit
	if(arm_clothes)
		if(!arm_clothes.unacidable)
			arm_clothes.acid_act(acidpwr)
			update_inv_gloves()
			update_inv_w_uniform()
			update_inv_wear_suit()
		else
			src << "Your [arm_clothes.name] protects your arms and hands from the acid!"
	else
		. = get_organ("r_arm")
		if(.)
			damaged += .
		. = get_organ("l_arm")
		if(.)
			damaged += .

	//LEGS & FEET//
	var/obj/item/clothing/leg_clothes = null
	if(shoes)
		leg_clothes = shoes
	if(w_uniform && (w_uniform.body_parts_covered & FEET) || w_uniform && (w_uniform.body_parts_covered & LEGS))
		leg_clothes = w_uniform
	if(wear_suit && (wear_suit.body_parts_covered & FEET) || wear_suit && (wear_suit.body_parts_covered & LEGS))
		leg_clothes = wear_suit
	if(leg_clothes)
		if(!leg_clothes.unacidable)
			leg_clothes.acid_act(acidpwr)
			update_inv_shoes()
			update_inv_w_uniform()
			update_inv_wear_suit()
		else
			src << "Your [leg_clothes.name] protects your legs and feet from the acid!"
	else
		. = get_organ("r_leg")
		if(.)
			damaged += .
		. = get_organ("l_leg")
		if(.)
			damaged += .

	//DAMAGE//
	for(var/obj/item/organ/limb/affecting in damaged)
		affecting.take_damage(2*toxpwr, toxpwr)

		if(affecting.name == "head")
			affecting.take_damage(2*toxpwr, toxpwr)
			if(prob(2*acidpwr)) //Applies disfigurement
				emote("scream")
				facial_hair_style = "Shaved"
				hair_style = "Bald"
				update_hair()
				status_flags |= DISFIGURED

		update_damage_overlays()

	//MELTING INVENTORY ITEMS//
	//these items are all outside of armour visually, so melt regardless.
	if(back)
		inventory_items_to_kill += back
	if(belt)
		inventory_items_to_kill += belt
	if(r_hand)
		inventory_items_to_kill += r_hand
	if(l_hand)
		inventory_items_to_kill += l_hand

	for(var/obj/item/I in inventory_items_to_kill)
		I.acid_act(acidpwr)

/mob/living/carbon/human/grabbedby(mob/living/user)
	if(w_uniform)
		w_uniform.add_fingerprint(user)
	..()

/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M as mob)
	if(..())
		var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
		if(check_shields(damage, "the [M.name]"))
			return 0
		var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
		var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone))
		var/armor = run_armor_check(affecting, "melee")
		apply_damage(damage, BRUTE, affecting, armor)
		updatehealth()
/*		if(armor >= 2) //why is this here?
		return */

/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L as mob)

	if(..()) //successful larva bite.
		var/damage = rand(1, 3)
		if(check_shields(damage, "the [L.name]"))
			return 0
		if(stat != DEAD)
			L.amount_grown = min(L.amount_grown + damage, L.max_grown)
			var/obj/item/organ/limb/affecting = get_organ(ran_zone(L.zone_sel.selecting))
			var/armor_block = run_armor_check(affecting, "melee")
			apply_damage(damage, BRUTE, affecting, armor_block)
			updatehealth()

/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M as mob)
	..()
	var/damage = rand(1, 3)

	if(M.is_adult)
		damage = rand(10, 35)
	else
		damage = rand(5, 25)

	if(check_shields(damage, "the [M.name]"))
		return 0

	var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")

	var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone))
	var/armor_block = run_armor_check(affecting, "melee")
	apply_damage(damage, BRUTE, affecting, armor_block)

	return
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)

	if(M.occupant.a_intent == "harm")
		if(M.damtype == "brute")
			step_away(src,M,15)
		var/obj/item/organ/limb/temp = get_organ(pick("chest", "chest", "chest", "head"))
		if(temp)
			var/update = 0
			switch(M.damtype)
				if("brute")
					if(M.force > 20)
						Paralyse(1)
					update |= temp.take_damage(rand(M.force/2, M.force), 0)
					playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
				if("fire")
					update |= temp.take_damage(0, rand(M.force/2, M.force))
					playsound(src, 'sound/items/Welder.ogg', 50, 1)
				if("tox")
					M.mech_toxin_damage(src)
				else
					return
			if(update)
				update_damage_overlays(0)
			updatehealth()

		visible_message("[M.name] has hit [src]!", \
								"[M.name] has hit [src]!")
		add_logs(M.occupant, src, "attacked", object=M, addition="(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")

	else
		..()

	return


code:
/mob/living/carbon/human
	languages = HUMAN
	hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
	//Hair colour and style
	var/hair_color = "000"
	var/hair_style = "Bald"

	//Facial hair colour and style
	var/facial_hair_color = "000"
	var/facial_hair_style = "Shaved"

	//Eye colour
	var/eye_color = "000"

	var/skin_tone = "caucasian1"	//Skin tone

	var/lip_style = null	//no lipstick by default- arguably misleading, as it could be used for general makeup

	var/age = 30		//Player's age (pure fluff)
	var/blood_type = "A+"	//Player's bloodtype

	var/underwear = "Nude"	//Which underwear the player wants
	var/undershirt = "Nude" //Which undershirt the player wants
	var/socks = "Nude" //Which socks the player wants
	var/backbag = 2		//Which backpack type the player has chosen. Nothing, Satchel or Backpack.

	//Equipment slots
	var/obj/item/wear_suit = null
	var/obj/item/w_uniform = null
	var/obj/item/shoes = null
	var/obj/item/belt = null
	var/obj/item/gloves = null
	var/obj/item/glasses = null
	//var/obj/item/head = null
	var/obj/item/ears = null
	var/obj/item/wear_id = null
	var/obj/item/r_store = null
	var/obj/item/l_store = null
	var/obj/item/s_store = null

	var/icon/base_icon_state = "caucasian1_m"

	var/list/organs = list() //Gets filled up in the constructor (human.dm, New() proc, line 24. I'm sick and tired of missing comments. -Agouri

	var/special_voice = "" // For changing our voice. Used by a symptom.

	var/xylophone = 0 //For the spoooooooky xylophone cooldown

	var/gender_ambiguous = 0 //if something goes wrong during gender reassignment this generates a line in examine

	var/blood_max = 0 //how much are we bleeding
	var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding

	var/datum/martial_art/martial_art = null

	var/name_override //For temporary visible name changes

license: mit


code:
/mob/living/carbon/human/restrained()
	if (handcuffed)
		return 1
	if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
		return 1
	return 0

/mob/living/carbon/human/canBeHandcuffed()
	return 1

//gets assignment from ID or ID inside PDA or PDA itself
//Useful when player do something with computers
/mob/living/carbon/human/proc/get_assignment(var/if_no_id = "No id", var/if_no_job = "No job")
	var/obj/item/weapon/card/id/id = get_idcard()
	if(id)
		. = id.assignment
	else
		var/obj/item/device/pda/pda = wear_id
		if(istype(pda))
			. = pda.ownjob
		else
			return if_no_id
	if(!.)
		return if_no_job

//gets name from ID or ID inside PDA or PDA itself
//Useful when player do something with computers
/mob/living/carbon/human/proc/get_authentification_name(var/if_no_id = "Unknown")
	var/obj/item/weapon/card/id/id = get_idcard()
	if(id)
		return id.registered_name
	var/obj/item/device/pda/pda = wear_id
	if(istype(pda))
		return pda.owner
	return if_no_id

//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
/mob/living/carbon/human/get_visible_name()
	var/face_name = get_face_name("")
	var/id_name = get_id_name("")
	if(name_override)
		return name_override
	if(face_name)
		if(id_name && (id_name != face_name))
			return "[face_name] (as [id_name])"
		return face_name
	if(id_name)
		return id_name
	return "Unknown"

//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when Fluacided or when updating a human's name variable
/mob/living/carbon/human/proc/get_face_name(if_no_face="Unknown")
	if( wear_mask && (wear_mask.flags_inv&HIDEFACE) )	//Wearing a mask which hides our face, use id-name if possible
		return if_no_face
	if( head && (head.flags_inv&HIDEFACE) )
		return if_no_face		//Likewise for hats
	var/obj/item/organ/limb/O = get_organ("head")
	if( (status_flags&DISFIGURED) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name )	//disfigured. use id-name if possible
		return if_no_face
	return real_name

//gets name from ID or PDA itself, ID inside PDA doesn't matter
//Useful when player is being seen by other mobs
/mob/living/carbon/human/proc/get_id_name(var/if_no_id = "Unknown")
	var/obj/item/weapon/storage/wallet/wallet = wear_id
	var/obj/item/device/pda/pda = wear_id
	var/obj/item/weapon/card/id/id = wear_id
	if(istype(wallet))		id = wallet.front_id
	if(istype(id))			. = id.registered_name
	else if(istype(pda))	. = pda.owner
	if(!.) 					. = if_no_id	//to prevent null-names making the mob unclickable
	return

//gets ID card object from special clothes slot or null.
/mob/living/carbon/human/proc/get_idcard()
	if(wear_id)
		return wear_id.GetID()

///checkeyeprot()
///Returns a number between -1 to 2
/mob/living/carbon/human/check_eye_prot()
	var/number = 0
	if(istype(src.head, /obj/item/clothing/head))			//are they wearing something on their head
		var/obj/item/clothing/head/HFP = src.head			//if yes gets the flash protection value from that item
		number += HFP.flash_protect
	if(istype(src.glasses, /obj/item/clothing/glasses))		//glasses
		var/obj/item/clothing/glasses/GFP = src.glasses
		number += GFP.flash_protect
	if(istype(src.wear_mask, /obj/item/clothing/mask))		//mask
		var/obj/item/clothing/mask/MFP = src.wear_mask
		number += MFP.flash_protect
	var/obj/item/cybernetic_implant/eyes/EFP = locate() in src
	if(EFP)
		number += EFP.flash_protect
	return number

/mob/living/carbon/human/check_ear_prot()
	if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
		return 1

///tintcheck()
///Checks eye covering items for visually impairing tinting, such as welding masks
///Checked in life.dm. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = You can see jack, but you can't see shit.
/mob/living/carbon/human/tintcheck()
	var/tinted = 0
	if(istype(src.head, /obj/item/clothing/head))
		var/obj/item/clothing/head/HT = src.head
		tinted += HT.tint
	if(istype(src.glasses, /obj/item/clothing/glasses))
		var/obj/item/clothing/glasses/GT = src.glasses
		tinted += GT.tint
	if(istype(src.wear_mask, /obj/item/clothing/mask))
		var/obj/item/clothing/mask/MT = src.wear_mask
		tinted += MT.tint
	return tinted

/mob/living/carbon/human/abiotic(var/full_body = 0)
	if(full_body && ((src.l_hand && !( src.l_hand.flags&ABSTRACT )) || (src.r_hand && !( src.r_hand.flags&ABSTRACT )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.ears || src.gloves)))
		return 1

	if( (src.l_hand && !(src.l_hand.flags&ABSTRACT)) || (src.r_hand && !(src.r_hand.flags&ABSTRACT)) )
		return 1

	return 0

/mob/living/carbon/human/IsAdvancedToolUser()
	return 1//Humans can use guns and such

/mob/living/carbon/human/SpeciesCanConsume()
	return 1 // Humans can eat, drink, and be forced to do so

/mob/living/carbon/human/InCritical()
	return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)

/mob/living/carbon/human/reagent_check(datum/reagent/R)
	if(dna)
		var/bypass = dna.species.handle_chemicals(R,src)
		return bypass	// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
	else
		return 0


code:
/mob/living/carbon/human/movement_delay()
	if(dna)
		. += dna.species.movement_delay(src)

	. += ..()
	. += config.human_delay

/mob/living/carbon/human/Process_Spacemove(var/movement_dir = 0)

	if(..())
		return 1

	//Do we have a working jetpack
	if(istype(back, /obj/item/weapon/tank/jetpack) && isturf(loc)) //Second check is so you can't use a jetpack in a mech
		var/obj/item/weapon/tank/jetpack/J = back
		if((movement_dir || J.stabilization_on) && J.allow_thrust(0.01, src))
			return 1

	return 0

/mob/living/carbon/human/slip(var/s_amount, var/w_amount, var/obj/O, var/lube)
	if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
		return 0
	.=..()

/mob/living/carbon/human/mob_has_gravity()
	. = ..()
	if(!.)
		if(mob_negates_gravity())
			. = 1

/mob/living/carbon/human/mob_negates_gravity()
	return shoes && shoes.negates_gravity()

/mob/living/carbon/human/Move(NewLoc, direct)
	..()
	if(shoes)
		if(!lying)
			if(loc == NewLoc)
				if(!has_gravity(loc))
					return
				var/obj/item/clothing/shoes/S = shoes
				S.step_action()


code:
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
	if(dna)
		return dna.species.can_equip(I, slot, disable_warning, src)
	else
		switch(slot)
			if(slot_l_hand)
				if(l_hand)
					return 0
				return 1
			if(slot_r_hand)
				if(r_hand)
					return 0
				return 1
			if(slot_wear_mask)
				if(wear_mask)
					return 0
				if( !(I.slot_flags & SLOT_MASK) )
					return 0
				return 1
			if(slot_back)
				if(back)
					return 0
				if( !(I.slot_flags & SLOT_BACK) )
					return 0
				return 1
			if(slot_wear_suit)
				if(wear_suit)
					return 0
				if( !(I.slot_flags & SLOT_OCLOTHING) )
					return 0
				return 1
			if(slot_gloves)
				if(gloves)
					return 0
				if( !(I.slot_flags & SLOT_GLOVES) )
					return 0
				return 1
			if(slot_shoes)
				if(shoes)
					return 0
				if( !(I.slot_flags & SLOT_FEET) )
					return 0
				return 1
			if(slot_belt)
				if(belt)
					return 0
				if(!w_uniform)
					if(!disable_warning)
						src << "You need a jumpsuit before you can attach this [I.name]."
					return 0
				if( !(I.slot_flags & SLOT_BELT) )
					return
				return 1
			if(slot_glasses)
				if(glasses)
					return 0
				if( !(I.slot_flags & SLOT_EYES) )
					return 0
				return 1
			if(slot_head)
				if(head)
					return 0
				if( !(I.slot_flags & SLOT_HEAD) )
					return 0
				return 1
			if(slot_ears)
				if(ears)
					return 0
				if( !(I.slot_flags & SLOT_EARS) )
					return 0
				return 1
			if(slot_w_uniform)
				if(w_uniform)
					return 0
				if( !(I.slot_flags & SLOT_ICLOTHING) )
					return 0
				return 1
			if(slot_wear_id)
				if(wear_id)
					return 0
				if(!w_uniform)
					if(!disable_warning)
						src << "You need a jumpsuit before you can attach this [I.name]."
					return 0
				if( !(I.slot_flags & SLOT_ID) )
					return 0
				return 1
			if(slot_l_store)
				if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them.
					return 0
				if(l_store)
					return 0
				if(!w_uniform)
					if(!disable_warning)
						src << "You need a jumpsuit before you can attach this [I.name]."
					return 0
				if(I.slot_flags & SLOT_DENYPOCKET)
					return
				if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
					return 1
			if(slot_r_store)
				if(I.flags & NODROP)
					return 0
				if(r_store)
					return 0
				if(!w_uniform)
					if(!disable_warning)
						src << "You need a jumpsuit before you can attach this [I.name]."
					return 0
				if(I.slot_flags & SLOT_DENYPOCKET)
					return 0
				if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
					return 1
				return 0
			if(slot_s_store)
				if(I.flags & NODROP) //Suit storage NODROP items drop if you take a suit off, this is to prevent people exploiting this.
					return 0
				if(s_store)
					return 0
				if(!wear_suit)
					if(!disable_warning)
						src << "You need a suit before you can attach this [I.name]."
					return 0
				if(!wear_suit.allowed)
					if(!disable_warning)
						usr << "You somehow have a suit with no defined allowed items for suit storage, stop that."  //should be src?
					return 0
				if(I.w_class > 4)
					if(!disable_warning)
						usr << "The [I.name] is too big to attach."  //should be src?
					return 0
				if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, wear_suit.allowed) )  //ugly and un-polymorphic.
					return 1
				return 0
			if(slot_handcuffed)
				if(handcuffed)
					return 0
				if(!istype(I, /obj/item/weapon/restraints/handcuffs))
					return 0
				return 1
			if(slot_legcuffed)
				if(legcuffed)
					return 0
				if(!istype(I, /obj/item/weapon/restraints/legcuffs))
					return 0
				return 1
			if(slot_in_backpack)
				if (back && istype(back, /obj/item/weapon/storage/backpack))
					var/obj/item/weapon/storage/backpack/B = back
					if(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class)
						return 1
				return 0
		return 0 //Unsupported slot

/mob/living/carbon/human/verb/quick_equip()
	set name = "quick-equip"
	set hidden = 1

	if(ishuman(src))
		var/mob/living/carbon/human/H = src
		var/obj/item/I = H.get_active_hand()
		var/obj/item/weapon/storage/S = H.get_inactive_hand()
		if(!I)
			H << "You are not holding anything to equip."
			return
		if(H.equip_to_appropriate_slot(I))
			if(hand)
				update_inv_l_hand(0)
			else
				update_inv_r_hand(0)
		else if(s_active && s_active.can_be_inserted(I,1))	//if storage active insert there
			s_active.handle_item_insertion(I)
		else if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1))	//see if we have box in other hand
			S.handle_item_insertion(I)
		else
			S = H.get_item_by_slot(slot_belt)
			if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1))		//else we put in belt
				S.handle_item_insertion(I)
			else
				S = H.get_item_by_slot(slot_back)	//else we put in backpack
				if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1))
					S.handle_item_insertion(I)
				else
					H << "You are unable to equip that."

/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1)
	for(var/slot in slots)
		if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0))
			return slot
	if(qdel_on_fail)
		qdel(I)
	return null

// Return the item currently in the slot ID
/mob/living/carbon/human/get_item_by_slot(slot_id)
	switch(slot_id)
		if(slot_back)
			return back
		if(slot_wear_mask)
			return wear_mask
		if(slot_handcuffed)
			return handcuffed
		if(slot_legcuffed)
			return legcuffed
		if(slot_l_hand)
			return l_hand
		if(slot_r_hand)
			return r_hand
		if(slot_belt)
			return belt
		if(slot_wear_id)
			return wear_id
		if(slot_ears)
			return ears
		if(slot_glasses)
			return glasses
		if(slot_gloves)
			return gloves
		if(slot_head)
			return head
		if(slot_shoes)
			return shoes
		if(slot_wear_suit)
			return wear_suit
		if(slot_w_uniform)
			return w_uniform
		if(slot_l_store)
			return l_store
		if(slot_r_store)
			return r_store
		if(slot_s_store)
			return s_store
	return null

/mob/living/carbon/human/unEquip(obj/item/I)
	. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
	if(!. || !I)
		return

	if(I == wear_suit)
		if(s_store)
			unEquip(s_store, 1) //It makes no sense for your suit storage to stay on you if you drop your suit.
		wear_suit = null
		if(I.flags_inv & HIDEJUMPSUIT)
			update_inv_w_uniform()
		update_inv_wear_suit(0)
	else if(I == w_uniform)
		if(r_store)
			unEquip(r_store, 1) //Again, makes sense for pockets to drop.
		if(l_store)
			unEquip(l_store, 1)
		if(wear_id)
			unEquip(wear_id)
		if(belt)
			unEquip(belt)
		w_uniform = null
		update_suit_sensors()
		update_inv_w_uniform(0)
	else if(I == gloves)
		gloves = null
		update_inv_gloves(0)
	else if(I == glasses)
		glasses = null
		update_inv_glasses(0)
	else if(I == head)
		head = null
		if(I.flags & BLOCKHAIR)
			update_hair(0)	//rebuild hair
		update_inv_head(0)
	else if(I == ears)
		ears = null
		update_inv_ears(0)
	else if(I == shoes)
		shoes = null
		update_inv_shoes(0)
	else if(I == belt)
		belt = null
		update_inv_belt(0)
	else if(I == wear_mask)
		wear_mask = null
		if(I.flags & BLOCKHAIR)
			update_hair(0)	//rebuild hair
		if(internal)
			if(internals)
				internals.icon_state = "internal0"
			internal = null
		sec_hud_set_ID()
		update_inv_wear_mask(0)
	else if(I == wear_id)
		wear_id = null
		sec_hud_set_ID()
		update_inv_wear_id(0)
	else if(I == r_store)
		r_store = null
		update_inv_pockets(0)
	else if(I == l_store)
		l_store = null
		update_inv_pockets(0)
	else if(I == s_store)
		s_store = null
		update_inv_s_store(0)

//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot, redraw_mob = 1)
	if(!slot)	return
	if(!istype(I))	return

	if(I == l_hand)
		l_hand = null
	else if(I == r_hand)
		r_hand = null

	I.screen_loc = null // will get moved if inventory is visible
	I.loc = src
	I.equipped(src, slot)
	I.layer = 20

	switch(slot)
		if(slot_back)
			back = I
			update_inv_back(redraw_mob)
		if(slot_wear_mask)
			wear_mask = I
			if(wear_mask.flags & BLOCKHAIR)
				update_hair(redraw_mob)	//rebuild hair
			sec_hud_set_ID()
			update_inv_wear_mask(redraw_mob)
		if(slot_handcuffed)
			handcuffed = I
			update_inv_handcuffed(redraw_mob)
		if(slot_legcuffed)
			legcuffed = I
			update_inv_legcuffed(redraw_mob)
		if(slot_l_hand)
			l_hand = I
			update_inv_l_hand(redraw_mob)
		if(slot_r_hand)
			r_hand = I
			update_inv_r_hand(redraw_mob)
		if(slot_belt)
			belt = I
			update_inv_belt(redraw_mob)
		if(slot_wear_id)
			wear_id = I
			sec_hud_set_ID()
			update_inv_wear_id(redraw_mob)
		if(slot_ears)
			ears = I
			update_inv_ears(redraw_mob)
		if(slot_glasses)
			glasses = I
			update_inv_glasses(redraw_mob)
		if(slot_gloves)
			gloves = I
			update_inv_gloves(redraw_mob)
		if(slot_head)
			head = I
			if(head.flags & BLOCKHAIR)
				update_hair(redraw_mob)	//rebuild hair
			update_inv_head(redraw_mob)
		if(slot_shoes)
			shoes = I
			update_inv_shoes(redraw_mob)
		if(slot_wear_suit)
			wear_suit = I
			if(I.flags_inv & HIDEJUMPSUIT)
				update_inv_w_uniform()
			update_inv_wear_suit(redraw_mob)
		if(slot_w_uniform)
			w_uniform = I
			update_suit_sensors()
			update_inv_w_uniform(redraw_mob)
		if(slot_l_store)
			l_store = I
			update_inv_pockets(redraw_mob)
		if(slot_r_store)
			r_store = I
			update_inv_pockets(redraw_mob)
		if(slot_s_store)
			s_store = I
			update_inv_s_store(redraw_mob)
		if(slot_in_backpack)
			if(get_active_hand() == I)
				unEquip(I)
			I.loc = back
		else
			src << "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!"
			return


code:
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32

//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!

#define TINT_IMPAIR 2			//Threshold of tint level to apply weld mask overlay
#define TINT_BLIND 3			//Threshold of tint level to obscure vision fully

#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 460K point and you are on fire

#define COLD_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when your body temperature just passes the 260.15k safety point
#define COLD_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when your body temperature passes the 200K point
#define COLD_DAMAGE_LEVEL_3 3 //Amount of damage applied when your body temperature passes the 120K point

//Note that gas heat damage is only applied once every FOUR ticks.
#define HEAT_GAS_DAMAGE_LEVEL_1 2 //Amount of damage applied when the current breath's temperature just passes the 360.15k safety point
#define HEAT_GAS_DAMAGE_LEVEL_2 4 //Amount of damage applied when the current breath's temperature passes the 400K point
#define HEAT_GAS_DAMAGE_LEVEL_3 8 //Amount of damage applied when the current breath's temperature passes the 1000K point

#define COLD_GAS_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when the current breath's temperature just passes the 260.15k safety point
#define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point

/mob/living/carbon/human
	var/tinttotal = 0				// Total level of visualy impairing items

/mob/living/carbon/human/Life()
	set invisibility = 0
	set background = BACKGROUND_ENABLED

	if (notransform)
		return

	tinttotal = tintcheck() //here as both hud updates and status updates call it

	if(..())
		if(dna)
			for(var/datum/mutation/human/HM in dna.mutations)
				HM.on_life(src)

		//Stuff jammed in your limbs hurts
		handle_embedded_objects()
	//Update our name based on whether our face is obscured/disfigured
	name = get_visible_name()

	if(dna)
		dna.species.spec_life(src) // for mutantraces

/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
	..()
	var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )

	var/pressure_adjustment_coefficient = 1	//Determins how much the clothing you are wearing protects you in percent.
	if(wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE))
		pressure_adjustment_coefficient -= PRESSURE_SUIT_REDUCTION_COEFFICIENT
	if(head && (head.flags & STOPSPRESSUREDMAGE))
		pressure_adjustment_coefficient -= PRESSURE_HEAD_REDUCTION_COEFFICIENT
	pressure_adjustment_coefficient = max(pressure_adjustment_coefficient,0) //So it isn't less than 0
	pressure_difference = pressure_difference * pressure_adjustment_coefficient
	if(pressure > ONE_ATMOSPHERE)
		return ONE_ATMOSPHERE + pressure_difference
	else
		return ONE_ATMOSPHERE - pressure_difference

/mob/living/carbon/human/handle_disabilities()
	..()
	//Eyes
	if(!(disabilities & BLIND))
		if(tinttotal >= TINT_BLIND)		//covering your eyes heals blurry eyes faster
			eye_blurry = max(eye_blurry-2, 0)

	//Ears
	if(!(disabilities & DEAF))
		if(istype(ears, /obj/item/clothing/ears/earmuffs)) // earmuffs rest your ears, healing ear_deaf faster and ear_damage, but keeping you deaf.
			setEarDamage(max(ear_damage-0.10, 0), max(ear_deaf - 1, 1))

	if (getBrainLoss() >= 60 && stat != DEAD)
		if (prob(3))
			switch(pick(1,2,3))
				if(1)
					say(pick("IM A PONY NEEEEEEIIIIIIIIIGH", "without oxigen blob don't evoluate?", "CAPTAINS A COMDOM", "[pick("", "that faggot traitor")] [pick("joerge", "george", "gorge", "gdoruge")] [pick("mellens", "melons", "mwrlins")] is grifing me HAL;P!!!", "can u give me [pick("telikesis","halk","eppilapse")]?", "THe saiyans screwed", "Bi is THE BEST OF BOTH WORLDS>", "I WANNA PET TEH monkeyS", "stop grifing me!!!!", "SOTP IT#"))
				if(2)
					say(pick("FUS RO DAH","fucking 4rries!", "stat me", ">my face", "roll it easy!", "waaaaaagh!!!", "red wonz go fasta", "FOR TEH EMPRAH", "lol2cat", "dem dwarfs man, dem dwarfs", "SPESS MAHREENS", "hwee did eet fhor khayosss", "lifelike texture ;_;", "luv can bloooom", "PACKETS!!!"))
				if(3)
					emote("drool")

/mob/living/carbon/human/handle_mutations_and_radiation()
	if(dna)
		if(dna.species.handle_mutations_and_radiation(src))
			..()

/mob/living/carbon/human/breathe()
	if(dna)
		dna.species.breathe(src)

	return

/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
	if(dna)
		dna.species.handle_environment(environment, src)

	return

///FIRE CODE
/mob/living/carbon/human/handle_fire()
	if(dna)
		dna.species.handle_fire(src)
	if(..())
		return
	var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
	if(wear_suit)
		if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
			thermal_protection += (wear_suit.max_heat_protection_temperature*0.7)
	if(head)
		if(head.max_heat_protection_temperature >= FIRE_HELM_MAX_TEMP_PROTECT)
			thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD)
	thermal_protection = round(thermal_protection)
	if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
		return
	if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT)
		bodytemperature += 11
		return
	else
		bodytemperature += BODYTEMP_HEATING_MAX
	return

/mob/living/carbon/human/IgniteMob()
	if(dna)
		dna.species.IgniteMob(src)
	else
		..()

/mob/living/carbon/human/ExtinguishMob()
	if(dna)
		dna.species.ExtinguishMob(src)
	else
		..()
//END FIRE CODE

/mob/living/carbon/human/proc/stabilize_temperature_from_calories()
	switch(bodytemperature)
		if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
			if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
				nutrition -= 2
			var/body_temperature_difference = 310.15 - bodytemperature
			bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
		if(260.15 to 360.15)
			var/body_temperature_difference = 310.15 - bodytemperature
			bodytemperature += body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR
		if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
			//We totally need a sweat system cause it totally makes sense...~
			var/body_temperature_difference = 310.15 - bodytemperature
			bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM)	//We're dealing with negative numbers

//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
	var/thermal_protection_flags = 0
	//Handle normal clothing
	if(head)
		if(head.max_heat_protection_temperature && head.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= head.heat_protection
	if(wear_suit)
		if(wear_suit.max_heat_protection_temperature && wear_suit.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= wear_suit.heat_protection
	if(w_uniform)
		if(w_uniform.max_heat_protection_temperature && w_uniform.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= w_uniform.heat_protection
	if(shoes)
		if(shoes.max_heat_protection_temperature && shoes.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= shoes.heat_protection
	if(gloves)
		if(gloves.max_heat_protection_temperature && gloves.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= gloves.heat_protection
	if(wear_mask)
		if(wear_mask.max_heat_protection_temperature && wear_mask.max_heat_protection_temperature >= temperature)
			thermal_protection_flags |= wear_mask.heat_protection

	return thermal_protection_flags

/mob/living/carbon/human/proc/get_heat_protection(temperature) //Temperature is the temperature you're being exposed to.
	var/thermal_protection_flags = get_heat_protection_flags(temperature)

	var/thermal_protection = 0.0
	if(thermal_protection_flags)
		if(thermal_protection_flags & HEAD)
			thermal_protection += THERMAL_PROTECTION_HEAD
		if(thermal_protection_flags & CHEST)
			thermal_protection += THERMAL_PROTECTION_CHEST
		if(thermal_protection_flags & GROIN)
			thermal_protection += THERMAL_PROTECTION_GROIN
		if(thermal_protection_flags & LEG_LEFT)
			thermal_protection += THERMAL_PROTECTION_LEG_LEFT
		if(thermal_protection_flags & LEG_RIGHT)
			thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
		if(thermal_protection_flags & FOOT_LEFT)
			thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
		if(thermal_protection_flags & FOOT_RIGHT)
			thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
		if(thermal_protection_flags & ARM_LEFT)
			thermal_protection += THERMAL_PROTECTION_ARM_LEFT
		if(thermal_protection_flags & ARM_RIGHT)
			thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
		if(thermal_protection_flags & HAND_LEFT)
			thermal_protection += THERMAL_PROTECTION_HAND_LEFT
		if(thermal_protection_flags & HAND_RIGHT)
			thermal_protection += THERMAL_PROTECTION_HAND_RIGHT

	return min(1,thermal_protection)

//See proc/get_heat_protection_flags(temperature) for the description of this proc.
/mob/living/carbon/human/proc/get_cold_protection_flags(temperature)
	var/thermal_protection_flags = 0
	//Handle normal clothing

	if(head)
		if(head.min_cold_protection_temperature && head.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= head.cold_protection
	if(wear_suit)
		if(wear_suit.min_cold_protection_temperature && wear_suit.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= wear_suit.cold_protection
	if(w_uniform)
		if(w_uniform.min_cold_protection_temperature && w_uniform.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= w_uniform.cold_protection
	if(shoes)
		if(shoes.min_cold_protection_temperature && shoes.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= shoes.cold_protection
	if(gloves)
		if(gloves.min_cold_protection_temperature && gloves.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= gloves.cold_protection
	if(wear_mask)
		if(wear_mask.min_cold_protection_temperature && wear_mask.min_cold_protection_temperature <= temperature)
			thermal_protection_flags |= wear_mask.cold_protection

	return thermal_protection_flags

/mob/living/carbon/human/proc/get_cold_protection(temperature)

	if(dna.check_mutation(COLDRES))
		return 1 //Fully protected from the cold.

	if(dna && COLDRES in dna.species.specflags)
		return 1

	temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
	var/thermal_protection_flags = get_cold_protection_flags(temperature)

	var/thermal_protection = 0.0
	if(thermal_protection_flags)
		if(thermal_protection_flags & HEAD)
			thermal_protection += THERMAL_PROTECTION_HEAD
		if(thermal_protection_flags & CHEST)
			thermal_protection += THERMAL_PROTECTION_CHEST
		if(thermal_protection_flags & GROIN)
			thermal_protection += THERMAL_PROTECTION_GROIN
		if(thermal_protection_flags & LEG_LEFT)
			thermal_protection += THERMAL_PROTECTION_LEG_LEFT
		if(thermal_protection_flags & LEG_RIGHT)
			thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
		if(thermal_protection_flags & FOOT_LEFT)
			thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
		if(thermal_protection_flags & FOOT_RIGHT)
			thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
		if(thermal_protection_flags & ARM_LEFT)
			thermal_protection += THERMAL_PROTECTION_ARM_LEFT
		if(thermal_protection_flags & ARM_RIGHT)
			thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
		if(thermal_protection_flags & HAND_LEFT)
			thermal_protection += THERMAL_PROTECTION_HAND_LEFT
		if(thermal_protection_flags & HAND_RIGHT)
			thermal_protection += THERMAL_PROTECTION_HAND_RIGHT

	return min(1,thermal_protection)

/mob/living/carbon/human/handle_chemicals_in_body()
	..()
	if(dna)
		dna.species.handle_chemicals_in_body(src)
	for(var/obj/item/I in src)
		I.OnMobLife(src)

	return //TODO: DEFERRED

/mob/living/carbon/human/handle_vision()
	client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask)
	if(machine)
		if(!machine.check_eye(src))		reset_view(null)
	else
		if(!client.adminobs)			reset_view(null)

	if(dna)
		dna.species.handle_vision(src)

/mob/living/carbon/human/handle_hud_icons()
	if(dna)
		dna.species.handle_hud_icons(src)

/mob/living/carbon/human/handle_random_events()
	// Puke if toxloss is too high
	if(!stat)
		if (getToxLoss() >= 45 && nutrition > 20)
			lastpuke ++
			if(lastpuke >= 25) // about 25 second delay I guess
				Stun(5)

				visible_message("[src] throws up!", \
						"[src] throws up!")
				playsound(loc, 'sound/effects/splat.ogg', 50, 1)

				var/turf/location = loc
				if (istype(location, /turf/simulated))
					location.add_vomit_floor(src, 1)

				nutrition -= 20
				adjustToxLoss(-3)

				// make it so you can only puke so fast
				lastpuke = 0

/mob/living/carbon/human/handle_changeling()
	if(mind)
		if(mind.changeling)
			mind.changeling.regenerate()
			if(hud_used)
				hud_used.lingchemdisplay.invisibility = 0
				hud_used.lingchemdisplay.maptext = "
 [mind.changeling.chem_charges]
"
		else
			if(hud_used)
				hud_used.lingchemdisplay.invisibility = 101

/mob/living/carbon/human/has_smoke_protection()
	if(wear_mask)
		if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
			. = 1
	if(glasses)
		if(glasses.flags & BLOCK_GAS_SMOKE_EFFECT)
			. = 1
	if(head)
		if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
			. = 1
	return .
/mob/living/carbon/human/proc/handle_embedded_objects()
	for(var/obj/item/organ/limb/L in organs)
		for(var/obj/item/I in L.embedded_objects)
			if(prob(I.embedded_pain_chance))
				L.take_damage(I.w_class*I.embedded_pain_multiplier)
				src << "\the [I] embedded in your [L.getDisplayName()] hurts!"

			if(prob(I.embedded_fall_chance))
				L.take_damage(I.w_class*I.embedded_fall_pain_multiplier)
				L.embedded_objects -= I
				I.loc = get_turf(src)
				visible_message("\the [I] falls out of [name]'s [L.getDisplayName()]!","\the [I] falls out of your [L.getDisplayName()]!")

/mob/living/carbon/human/handle_heart()
	if(!heart_attack)
		return
	else
		losebreath += 5
		Weaken(1)
		adjustOxyLoss(5)
		adjustBruteLoss(1)
	return

#undef HUMAN_MAX_OXYLOSS


code:
/mob/living/carbon/human/Login()
	..()
	update_hud()
	return


code:
var/global/list/colored_mutraces = list( // these mutantraces are affected by mutant color
	"lizard",
	"plant",
	"pod",
	"slime",
	"jelly",
	"golem"
)

var/global/list/mutants_with_eyes = list( // these mutantraces have eyes
	"lizard",
	"plant",
	"pod",
	"jelly",
)

/mob/living/carbon/human/proc/check_mutrace(var/mutneeded = "mut1", var/mutneededalt = "mut2")
	if(dna)
		if(dna.mutantrace == mutneeded || dna.mutantrace == mutneededalt)
			return 1

	return 0


code:
/mob/living/carbon/human/say_quote(text)
	if(!text)
		return "says, \"...\"";	//not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
	var/ending = copytext(text, length(text))
	if (src.stuttering)
		return "stammers, \"[text]\"";
	if(src.slurring)
		return "slurs, \"[text]\"";
	if(isliving(src))
		var/mob/living/L = src
		if (L.getBrainLoss() >= 60)
			return "gibbers, \"[text]\"";
	if(ending == "?")
		return "asks, \"[text]\"";
	if(copytext(text, length(text) - 1) == "!!")
		return "yells, \"[text]\"";
	if(ending == "!")
		return "exclaims, \"[text]\"";

	if(dna)
		return "[dna.species.say_mod], \"[text]\"";

	return "says, \"[text]\"";

/mob/living/carbon/human/treat_message(message)
	if(dna)
		message = dna.species.handle_speech(message,src)
	if(viruses.len)
		for(var/datum/disease/pierrot_throat/D in viruses)
			var/list/temp_message = text2list(message, " ") //List each word in the message
			var/list/pick_list = list()
			for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line
				pick_list += i
			for(var/i=1, ((i <= D.stage) && (i <= temp_message.len)), i++) //Loop for each stage of the disease or until we run out of words
				if(prob(3 * D.stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12%
					var/H = pick(pick_list)
					if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
					temp_message[H] = "HONK"
					pick_list -= H //Make sure that you dont HONK the same word twice
				message = list2text(temp_message, " ")
	message = ..(message)
	if(dna)
		message = dna.mutations_say_mods(message)
	return message

/mob/living/carbon/human/GetVoice()
	if(istype(wear_mask, /obj/item/clothing/mask/gas/voice))
		var/obj/item/clothing/mask/gas/voice/V = wear_mask
		if(V.vchange && wear_id)
			var/obj/item/weapon/card/id/idcard = wear_id.GetID()
			if(istype(idcard))
				return idcard.registered_name
			else
				return real_name
		else
			return real_name
	if(mind && mind.changeling && mind.changeling.mimicing)
		return mind.changeling.mimicing
	if(GetSpecialVoice())
		return GetSpecialVoice()
	return real_name

/mob/living/carbon/human/IsVocal()
	if(mind)
		return !mind.miming
	return 1

/mob/living/carbon/human/proc/SetSpecialVoice(var/new_voice)
	if(new_voice)
		special_voice = new_voice
	return

/mob/living/carbon/human/proc/UnsetSpecialVoice()
	special_voice = ""
	return

/mob/living/carbon/human/proc/GetSpecialVoice()
	return special_voice

/mob/living/carbon/human/binarycheck()
	if(ears)
		var/obj/item/device/radio/headset/dongle = ears
		if(!istype(dongle)) return 0
		if(dongle.translate_binary) return 1

/mob/living/carbon/human/radio(message, message_mode)
	. = ..()
	if(. != 0)
		return .

	switch(message_mode)
		if(MODE_HEADSET)
			if (ears)
				ears.talk_into(src, message)
			return ITALICS | REDUCE_RANGE

		if(MODE_SECURE_HEADSET)
			if (ears)
				ears.talk_into(src, message, 1)
			return ITALICS | REDUCE_RANGE

		if(MODE_DEPARTMENT)
			if (ears)
				ears.talk_into(src, message, message_mode)
			return ITALICS | REDUCE_RANGE

	if(message_mode in radiochannels)
		if(ears)
			ears.talk_into(src, message, message_mode)
			return ITALICS | REDUCE_RANGE

	return 0

/mob/living/carbon/human/get_alt_name()
	if(name != GetVoice())
		return " (as [get_id_name("Unknown")])"

/mob/living/carbon/human/proc/forcesay(list/append) //this proc is at the bottom of the file because quote fuckery makes notepad++ cri
	if(stat == CONSCIOUS)
		if(client)
			var/virgin = 1	//has the text been modified yet?
			var/temp = winget(client, "input", "text")
			if(findtextEx(temp, "Say \"", 1, 7) && length(temp) > 5)	//"case sensitive means

				temp = replacetext(temp, ";", "")	//general radio

				if(findtext(trim_left(temp), ":", 6, 7))	//dept radio
					temp = copytext(trim_left(temp), 8)
					virgin = 0

				if(virgin)
					temp = copytext(trim_left(temp), 6)	//normal speech
					virgin = 0

				while(findtext(trim_left(temp), ":", 1, 2))	//dept radio again (necessary)
					temp = copytext(trim_left(temp), 3)

				if(findtext(temp, "*", 1, 2))	//emotes
					return

				var/trimmed = trim_left(temp)
				if(length(trimmed))
					if(append)
						temp += pick(append)

					say(temp)
				winset(client, "input", "text=[null]")


code:
// This code handles different species in the game.

#define TINT_IMPAIR 2
#define TINT_BLIND 3

#define HUMAN_MAX_OXYLOSS 3
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)

#define HEAT_DAMAGE_LEVEL_1 2
#define HEAT_DAMAGE_LEVEL_2 3
#define HEAT_DAMAGE_LEVEL_3 8

#define COLD_DAMAGE_LEVEL_1 0.5
#define COLD_DAMAGE_LEVEL_2 1.5
#define COLD_DAMAGE_LEVEL_3 3

#define HEAT_GAS_DAMAGE_LEVEL_1 2
#define HEAT_GAS_DAMAGE_LEVEL_2 4
#define HEAT_GAS_DAMAGE_LEVEL_3 8

#define COLD_GAS_DAMAGE_LEVEL_1 0.5
#define COLD_GAS_DAMAGE_LEVEL_2 1.5
#define COLD_GAS_DAMAGE_LEVEL_3 3

/datum/species
	var/id = null		// if the game needs to manually check your race to do something not included in a proc here, it will use this
	var/name = null		// this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
	var/roundstart = 0	// can this mob be chosen at roundstart? (assuming the config option is checked?)
	var/default_color = "#FFF"	// if alien colors are disabled, this is the color that will be used by that race

	var/eyes = "eyes"	// which eyes the race uses. at the moment, the only types of eyes are "eyes" (regular eyes) and "jelleyes" (three eyes)
	var/sexes = 1		// whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
	var/hair_color = null	// this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
	var/hair_alpha = 255	// the alpha used by the hair. 255 is completely solid, 0 is transparent.
	var/use_skintones = 0	// does it use skintones or not? (spoiler alert this is only used by humans)
	var/exotic_blood = null	// If your race wants to bleed something other than bog standard blood, change this.
	var/meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
	var/list/no_equip = list()	// slots the race can't equip stuff to
	var/nojumpsuit = 0	// this is sorta... weird. it basically lets you equip stuff that usually needs jumpsuits without one, like belts and pockets and ids

	var/say_mod = "says"	// affects the speech message

	var/list/mutant_bodyparts = list() 	// Parts of the body that are diferent enough from the standard human model that they cause clipping with some equipment

	var/speedmod = 0	// this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
	var/armor = 0		// overall defense for the race... or less defense, if it's negative.
	var/brutemod = 1	// multiplier for brute damage
	var/burnmod = 1		// multiplier for burn damage
	var/coldmod = 1		// multiplier for cold damage
	var/heatmod = 1		// multiplier for heat damage
	var/punchmod = 0	// adds to the punch damage

	var/invis_sight = SEE_INVISIBLE_LIVING
	var/darksight = 2

	// species flags. these can be found in flags.dm
	var/list/specflags = list()

	var/attack_verb = "punch"	// punch-specific attack verb
	var/sound/attack_sound = 'sound/weapons/punch1.ogg'
	var/sound/miss_sound = 'sound/weapons/punchmiss.ogg'

	var/mob/living/list/ignored_by = list()	// list of mobs that will ignore this species

	///////////
	// PROCS //
	///////////

/datum/species/proc/update_base_icon_state(var/mob/living/carbon/human/H)
	if(H.disabilities & HUSK)
		H.remove_overlay(SPECIES_LAYER) // races lose their color
		return "husk"
	else if(sexes)
		if(use_skintones)
			return "[H.skin_tone]_[(H.gender == FEMALE) ? "f" : "m"]"
		else
			return "[id]_[(H.gender == FEMALE) ? "f" : "m"]"
	else
		return "[id]"

/datum/species/proc/update_color(var/mob/living/carbon/human/H)
	H.remove_overlay(SPECIES_LAYER)

	var/image/standing

	var/g = (H.gender == FEMALE) ? "f" : "m"

	if(!config || !config.mutant_colors)
		H.dna.mutant_color = default_color

	if(MUTCOLORS in specflags)
		var/image/spec_base
		var/icon_state_string = "[id]_"
		if(sexes)
			icon_state_string += "[g]_s"
		else
			icon_state_string += "_s"

		spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = icon_state_string, "layer" = -SPECIES_LAYER)

		spec_base.color = "#[H.dna.mutant_color]"
		standing = spec_base

	if(standing)
		H.overlays_standing[SPECIES_LAYER]	+= standing

	H.apply_overlay(SPECIES_LAYER)

/datum/species/proc/handle_hair(var/mob/living/carbon/human/H)
	H.remove_overlay(HAIR_LAYER)

	var/datum/sprite_accessory/S
	var/list/standing	= list()

	if(H.facial_hair_style && FACEHAIR in specflags)
		S = facial_hair_styles_list[H.facial_hair_style]
		if(S)
			var/image/img_facial_s

			img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER)

			if(hair_color)
				if(hair_color == "mutcolor")
					if(!config.mutant_colors)
						img_facial_s.color = "#" + default_color
					else
						img_facial_s.color = "#" + H.dna.mutant_color
				else
					img_facial_s.color = "#" + hair_color
			else
				img_facial_s.color = "#" + H.facial_hair_color
			img_facial_s.alpha = hair_alpha

			standing	+= img_facial_s

	//Applies the debrained overlay if there is no brain
	if(!H.getorgan(/obj/item/organ/brain))
		standing	+= image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER)

	if((H.wear_suit) && (H.wear_suit.hooded) && (H.wear_suit.suittoggled == 1))
		if(standing.len)
			H.overlays_standing[HAIR_LAYER]    = standing
		H.apply_overlay(HAIR_LAYER)
		return

	else if(H.hair_style && HAIR in specflags)
		S = hair_styles_list[H.hair_style]
		if(S)
			var/image/img_hair_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER)

			img_hair_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER)

			if(hair_color)
				if(hair_color == "mutcolor")
					if(!config.mutant_colors)
						img_hair_s.color = "#" + default_color
					else
						img_hair_s.color = "#" + H.dna.mutant_color
				else
					img_hair_s.color = "#" + hair_color
			else
				img_hair_s.color = "#" + H.hair_color
			img_hair_s.alpha = hair_alpha

			standing	+= img_hair_s

	if(standing.len)
		H.overlays_standing[HAIR_LAYER]	= standing

	H.apply_overlay(HAIR_LAYER)
	return

/datum/species/proc/handle_body(var/mob/living/carbon/human/H)
	H.remove_overlay(BODY_LAYER)

	var/list/standing	= list()

	handle_mutant_bodyparts(H)

	// lipstick
	if(H.lip_style && LIPS in specflags)
		standing	+= image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[H.lip_style]_s", "layer" = -BODY_LAYER)

	// eyes
	if(EYECOLOR in specflags)
		var/image/img_eyes_s = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "[eyes]_s", "layer" = -BODY_LAYER)
		img_eyes_s.color = "#" + H.eye_color
		standing	+= img_eyes_s

	//Underwear, Undershirts & Socks
	if(H.underwear)
		var/datum/sprite_accessory/underwear/U = underwear_list[H.underwear]
		if(U)
			standing	+= image("icon"=U.icon, "icon_state"="[U.icon_state]_s", "layer"=-BODY_LAYER)

	if(H.undershirt)
		var/datum/sprite_accessory/undershirt/U2 = undershirt_list[H.undershirt]
		if(U2)
			if(H.dna && H.dna.species.sexes && H.gender == FEMALE)
				standing	+=	H.wear_female_version(U2.icon_state, U2.icon, BODY_LAYER)
			else
				standing	+= image("icon"=U2.icon, "icon_state"="[U2.icon_state]_s", "layer"=-BODY_LAYER)

	if(H.socks)
		var/datum/sprite_accessory/socks/U3 = socks_list[H.socks]
		if(U3)
			standing	+= image("icon"=U3.icon, "icon_state"="[U3.icon_state]_s", "layer"=-BODY_LAYER)

	if(standing.len)
		H.overlays_standing[BODY_LAYER] = standing

	H.apply_overlay(BODY_LAYER)

	return

/datum/species/proc/handle_mutant_bodyparts(var/mob/living/carbon/human/H)
	var/list/bodyparts_to_add = mutant_bodyparts.Copy()
	var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
	var/list/standing	= list()

	H.remove_overlay(BODY_BEHIND_LAYER)
	H.remove_overlay(BODY_ADJ_LAYER)
	H.remove_overlay(BODY_FRONT_LAYER)

	if(!mutant_bodyparts)
		return

	if("tail" in mutant_bodyparts)
		if(H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
			bodyparts_to_add -= "tail"

	if("snout" in mutant_bodyparts) //Take a closer look at that snout!
		if(H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE))
			bodyparts_to_add -= "snout"

	if(!bodyparts_to_add)
		return

	var/icon_state_string = "[id]_"
	var/g = (H.gender == FEMALE) ? "f" : "m"
	var/image/I

	if(sexes)
		icon_state_string += "[g]_s"
	else
		icon_state_string += "_s"

	if(!config || (config && !config.mutant_colors))
		H.dna.mutant_color = default_color

	for(var/layer in relevent_layers)
		for(var/bodypart in bodyparts_to_add)
			I = image("icon" = 'icons/mob/mutant_bodyparts.dmi', "icon_state" = "[icon_state_string]_[bodypart]_[layer]", "layer" =- layer)
			I.color = "#[H.dna.mutant_color]"
			standing += I
		H.overlays_standing[layer] = standing.Copy()
		standing = list()

	H.apply_overlay(BODY_BEHIND_LAYER)
	H.apply_overlay(BODY_ADJ_LAYER)
	H.apply_overlay(BODY_FRONT_LAYER)

/datum/species/proc/spec_life(var/mob/living/carbon/human/H)
	return

/datum/species/proc/spec_death(var/gibbed, var/mob/living/carbon/human/H)
	return

/datum/species/proc/auto_equip(var/mob/living/carbon/human/H)
	// handles the equipping of species-specific gear
	return

/datum/species/proc/can_equip(var/obj/item/I, var/slot, var/disable_warning, var/mob/living/carbon/human/H)
	if(slot in no_equip)
		if(!(type in I.species_exception))
			return 0

	switch(slot)
		if(slot_l_hand)
			if(H.l_hand)
				return 0
			return 1
		if(slot_r_hand)
			if(H.r_hand)
				return 0
			return 1
		if(slot_wear_mask)
			if(H.wear_mask)
				return 0
			if( !(I.slot_flags & SLOT_MASK) )
				return 0
			return 1
		if(slot_back)
			if(H.back)
				return 0
			if( !(I.slot_flags & SLOT_BACK) )
				return 0
			return 1
		if(slot_wear_suit)
			if(H.wear_suit)
				return 0
			if( !(I.slot_flags & SLOT_OCLOTHING) )
				return 0
			return 1
		if(slot_gloves)
			if(H.gloves)
				return 0
			if( !(I.slot_flags & SLOT_GLOVES) )
				return 0
			return 1
		if(slot_shoes)
			if(H.shoes)
				return 0
			if( !(I.slot_flags & SLOT_FEET) )
				return 0
			return 1
		if(slot_belt)
			if(H.belt)
				return 0
			if(!H.w_uniform && !nojumpsuit)
				if(!disable_warning)
					H << "You need a jumpsuit before you can attach this [I.name]."
				return 0
			if( !(I.slot_flags & SLOT_BELT) )
				return
			return 1
		if(slot_glasses)
			if(H.glasses)
				return 0
			if( !(I.slot_flags & SLOT_EYES) )
				return 0
			return 1
		if(slot_head)
			if(H.head)
				return 0
			if( !(I.slot_flags & SLOT_HEAD) )
				return 0
			return 1
		if(slot_ears)
			if(H.ears)
				return 0
			if( !(I.slot_flags & SLOT_EARS) )
				return 0
			return 1
		if(slot_w_uniform)
			if(H.w_uniform)
				return 0
			if( !(I.slot_flags & SLOT_ICLOTHING) )
				return 0
			return 1
		if(slot_wear_id)
			if(H.wear_id)
				return 0
			if(!H.w_uniform && !nojumpsuit)
				if(!disable_warning)
					H << "You need a jumpsuit before you can attach this [I.name]."
				return 0
			if( !(I.slot_flags & SLOT_ID) )
				return 0
			return 1
		if(slot_l_store)
			if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them.
				return 0
			if(H.l_store)
				return 0
			if(!H.w_uniform && !nojumpsuit)
				if(!disable_warning)
					H << "You need a jumpsuit before you can attach this [I.name]."
				return 0
			if(I.slot_flags & SLOT_DENYPOCKET)
				return
			if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
				return 1
		if(slot_r_store)
			if(I.flags & NODROP)
				return 0
			if(H.r_store)
				return 0
			if(!H.w_uniform && !nojumpsuit)
				if(!disable_warning)
					H << "You need a jumpsuit before you can attach this [I.name]."
				return 0
			if(I.slot_flags & SLOT_DENYPOCKET)
				return 0
			if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
				return 1
			return 0
		if(slot_s_store)
			if(I.flags & NODROP)
				return 0
			if(H.s_store)
				return 0
			if(!H.wear_suit)
				if(!disable_warning)
					H << "You need a suit before you can attach this [I.name]."
				return 0
			if(!H.wear_suit.allowed)
				if(!disable_warning)
					H << "You somehow have a suit with no defined allowed items for suit storage, stop that."
				return 0
			if(I.w_class > 4)
				if(!disable_warning)
					H << "The [I.name] is too big to attach."  //should be src?
				return 0
			if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, H.wear_suit.allowed) )
				return 1
			return 0
		if(slot_handcuffed)
			if(H.handcuffed)
				return 0
			if(!istype(I, /obj/item/weapon/restraints/handcuffs))
				return 0
			return 1
		if(slot_legcuffed)
			if(H.legcuffed)
				return 0
			if(!istype(I, /obj/item/weapon/restraints/legcuffs))
				return 0
			return 1
		if(slot_in_backpack)
			if (H.back && istype(H.back, /obj/item/weapon/storage/backpack))
				var/obj/item/weapon/storage/backpack/B = H.back
				if(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class)
					return 1
			return 0
	return 0 //Unsupported slot

/datum/species/proc/before_equip_job(var/datum/job/J, var/mob/living/carbon/human/H)
	return

/datum/species/proc/after_equip_job(var/datum/job/J, var/mob/living/carbon/human/H)
	return

/datum/species/proc/handle_chemicals(var/datum/reagent/chem, var/mob/living/carbon/human/H)
	return 0

/datum/species/proc/handle_speech(var/message, var/mob/living/carbon/human/H)
	return message

////////
	//LIFE//
	////////

/datum/species/proc/handle_chemicals_in_body(var/mob/living/carbon/human/H)

	//The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
	if(H.disabilities & FAT)
		if(H.overeatduration < 100)
			H << "You feel fit again!"
			H.disabilities &= ~FAT
			H.update_inv_w_uniform(0)
			H.update_inv_wear_suit()
	else
		if(H.overeatduration > 500)
			H << "You suddenly feel blubbery!"
			H.disabilities |= FAT
			H.update_inv_w_uniform(0)
			H.update_inv_wear_suit()

	// nutrition decrease and satiety
	if (H.nutrition > 0 && H.stat != 2)
		var/hunger_rate = HUNGER_FACTOR
		if(H.satiety > 0)
			H.satiety--
		if(H.satiety < 0)
			H.satiety++
			if(prob(round(-H.satiety/40)))
				H.Jitter(5)
			hunger_rate = 3 * HUNGER_FACTOR
		H.nutrition = max (0, H.nutrition - hunger_rate)

	if (H.nutrition > NUTRITION_LEVEL_FULL)
		if(H.overeatduration < 600) //capped so people don't take forever to unfat
			H.overeatduration++
	else
		if(H.overeatduration > 1)
			H.overeatduration -= 2 //doubled the unfat rate

	//metabolism change
	if(H.nutrition > NUTRITION_LEVEL_FAT)
		H.metabolism_efficiency = 1
	else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80)
		if(H.metabolism_efficiency != 1.25)
			H << "You feel vigorous."
			H.metabolism_efficiency = 1.25
	else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
		if(H.metabolism_efficiency != 0.8)
			H << "You feel sluggish."
		H.metabolism_efficiency = 0.8
	else
		if(H.metabolism_efficiency == 1.25)
			H << "You no longer feel vigorous."
		H.metabolism_efficiency = 1

	H.updatehealth()

	return

/datum/species/proc/handle_vision(var/mob/living/carbon/human/H)
	if( H.stat == DEAD )
		H.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
		H.see_in_dark = 8
		if(!H.druggy)		H.see_invisible = SEE_INVISIBLE_LEVEL_TWO
	else
		if(!(SEE_TURFS & H.permanent_sight_flags))
			H.sight &= ~SEE_TURFS
		if(!(SEE_MOBS & H.permanent_sight_flags))
			H.sight &= ~SEE_MOBS
		if(!(SEE_OBJS & H.permanent_sight_flags))
			H.sight &= ~SEE_OBJS

		if(H.remote_view)
			H.sight |= SEE_TURFS
			H.sight |= SEE_MOBS
			H.sight |= SEE_OBJS

		H.see_in_dark = (H.sight == SEE_TURFS|SEE_MOBS|SEE_OBJS) ? 8 : darksight
		var/see_temp = H.see_invisible
		H.see_invisible = invis_sight

		if(H.seer)
			H.see_invisible = SEE_INVISIBLE_OBSERVER

		if(H.glasses)
			if(istype(H.glasses, /obj/item/clothing/glasses))
				var/obj/item/clothing/glasses/G = H.glasses
				H.sight |= G.vision_flags
				H.see_in_dark = G.darkness_view
				H.see_invisible = G.invis_view
		if(H.druggy)	//Override for druggy
			H.see_invisible = see_temp

		if(H.see_override)	//Override all
			H.see_invisible = H.see_override

		//	This checks how much the mob's eyewear impairs their vision
		if(H.tinttotal >= TINT_IMPAIR)
			if(tinted_weldhelh)
				if(H.tinttotal >= TINT_BLIND)
					H.eye_blind = max(H.eye_blind, 1)
				if(H.client)
					H.client.screen += global_hud.darkMask

		if(H.blind)
			if(H.eye_blind)		H.blind.layer = 18
			else			H.blind.layer = 0

		if(!H.client)//no client, no screen to update
			return 1

		if( H.disabilities & NEARSIGHT && !istype(H.glasses, /obj/item/clothing/glasses/regular) )
			H.client.screen += global_hud.vimpaired
		if(H.eye_blurry)			H.client.screen += global_hud.blurry
		if(H.druggy)				H.client.screen += global_hud.druggy

		if(H.eye_stat > 20)
			if(H.eye_stat > 30)	H.client.screen += global_hud.darkMask
			else				H.client.screen += global_hud.vimpaired

	return 1

/datum/species/proc/handle_hud_icons(var/mob/living/carbon/human/H)
	if(H.healths)
		if(H.stat == DEAD)
			H.healths.icon_state = "health7"
		else
			switch(H.hal_screwyhud)
				if(1)	H.healths.icon_state = "health6"
				if(2)	H.healths.icon_state = "health7"
				else
					switch(H.health - H.staminaloss)
						if(100 to INFINITY)		H.healths.icon_state = "health0"
						if(80 to 100)			H.healths.icon_state = "health1"
						if(60 to 80)			H.healths.icon_state = "health2"
						if(40 to 60)			H.healths.icon_state = "health3"
						if(20 to 40)			H.healths.icon_state = "health4"
						if(0 to 20)				H.healths.icon_state = "health5"
						else					H.healths.icon_state = "health6"

	if(H.healthdoll)
		H.healthdoll.overlays.Cut()
		if(H.stat == DEAD)
			H.healthdoll.icon_state = "healthdoll_DEAD"
		else
			H.healthdoll.icon_state = "healthdoll_OVERLAY"
			for(var/obj/item/organ/limb/L in H.organs)
				var/damage = L.burn_dam + L.brute_dam
				var/comparison = (L.max_damage/5)
				var/icon_num = 0
				if(damage)
					icon_num = 1
				if(damage > (comparison))
					icon_num = 2
				if(damage > (comparison*2))
					icon_num = 3
				if(damage > (comparison*3))
					icon_num = 4
				if(damage > (comparison*4))
					icon_num = 5
				if(icon_num)
					H.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[L.name][icon_num]")

	switch(H.nutrition)
		if(NUTRITION_LEVEL_FULL to INFINITY)
			H.throw_alert("nutrition","fat")
		if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL)
			H.clear_alert("nutrition")
		if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
			H.throw_alert("nutrition","hungry")
		else
			H.throw_alert("nutrition","starving")

	return 1

/datum/species/proc/handle_mutations_and_radiation(var/mob/living/carbon/human/H)

	if(!(RADIMMUNE in specflags))
		if(H.radiation)
			if (H.radiation > 100)
				H.Weaken(10)
				H << "You feel weak."
				H.emote("collapse")

			switch(H.radiation)

				if(50 to 75)
					if(prob(5))
						H.Weaken(3)
						H << "You feel weak."
						H.emote("collapse")
					if(prob(15))
						if(!( H.hair_style == "Shaved") || !(H.hair_style == "Bald") || HAIR in specflags)
							H << "Your hair starts to fall out in clumps..."
							spawn(50)
								H.facial_hair_style = "Shaved"
								H.hair_style = "Bald"
								H.update_hair()

				if(75 to 100)
					if(prob(1))
						H << "You mutate!"
						randmutb(H)
						domutcheck(H,null)
						H.emote("gasp")
		return 1

////////////////
// MOVE SPEED //
////////////////

/datum/species/proc/movement_delay(var/mob/living/carbon/human/H)
	var/mspeed = 0

	var/hasjetpack = 0
	if(istype(H.back, /obj/item/weapon/tank/jetpack))
		var/obj/item/weapon/tank/jetpack/J = H.back
		if(J.allow_thrust(0.01, H))
			hasjetpack = 1
	var/grav = has_gravity(H)

	if(!grav && !hasjetpack)
		mspeed += 1 //Slower space without jetpack

	var/health_deficiency = (100 - H.health + H.staminaloss)
	if(health_deficiency >= 40)
		mspeed += (health_deficiency / 25)

	var/hungry = (500 - H.nutrition) / 5	//So overeat would be 100 and default level would be 80
	if(hungry >= 70)
		mspeed += hungry / 50

	if(H.wear_suit && grav)
		mspeed += H.wear_suit.slowdown
	if(H.shoes && grav)
		mspeed += H.shoes.slowdown
	if(H.back && grav)
		mspeed += H.back.slowdown

	if((H.disabilities & FAT) && grav)
		mspeed += 1.5
	if(H.bodytemperature < 283.222)
		mspeed += (283.222 - H.bodytemperature) / 10 * (grav+0.5)

	mspeed += speedmod

	if(H.status_flags & IGNORESLOWDOWN)
		mspeed = 0

	if(H.status_flags & GOTTAGOFAST)
		mspeed -= 1

	if(H.status_flags & GOTTAGOREALLYFAST)
		mspeed -= 2

	return mspeed

//////////////////
// ATTACK PROCS //
//////////////////

/datum/species/proc/spec_attack_hand(var/mob/living/carbon/human/M, var/mob/living/carbon/human/H)
	if((M != H) && H.check_shields(0, M.name))
		add_logs(M, H, "attempted to touch")
		H.visible_message("[M] attempted to touch [H]!")
		return 0

	switch(M.a_intent)
		if("help")
			if(H.health >= 0)
				H.help_shake_act(M)
				if(H != M)
					add_logs(M, H, "shaked")
				return 1

			//CPR
			if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
				M << "Remove your mask!"
				return 0
			if((H.head && (H.head.flags & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags & MASKCOVERSMOUTH)))
				M << "Remove their mask!"
				return 0

			if(H.cpr_time < world.time + 30)
				add_logs(M, H, "CPRed")
				M.visible_message("[M] is trying to perform CPR on [H]!", \
								"You try to perform CPR on [H]. Hold still!")
				if(!do_mob(M, H))
					M << "You fail to perform CPR on [H]!"
					return 0
				if((H.health >= -99 && H.health <= 0))
					H.cpr_time = world.time
					var/suff = min(H.getOxyLoss(), 7)
					H.adjustOxyLoss(-suff)
					H.updatehealth()
					M.visible_message("[M] performs CPR on [H]!")
					H << "You feel a breath of fresh air enter your lungs. It feels good."

		if("grab")
			H.grabbedby(M)
			return 1

		if("harm")
			add_logs(M, H, "punched")
			M.do_attack_animation(H)

			var/atk_verb = "punch"
			if(H.lying)
				atk_verb = "kick"
			else if(M.dna)
				atk_verb = M.dna.species.attack_verb

			var/damage = rand(0, 9)
			if(M.dna)
				damage += M.dna.species.punchmod

			if(!damage)
				if(M.dna)
					playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1)
				else
					playsound(H.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)

				H.visible_message("[M] has attempted to [atk_verb] [H]!")
				return 0

			var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_sel.selecting))
			var/armor_block = H.run_armor_check(affecting, "melee")

			if(M.dna)
				playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1)
			else
				playsound(H.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)

			H.visible_message("[M] has [atk_verb]ed [H]!", \
							"[M] has [atk_verb]ed [H]!")

			H.apply_damage(damage, BRUTE, affecting, armor_block)
			if((H.stat != DEAD) && damage >= 9)
				H.visible_message("[M] has weakened [H]!", \
								"[M] has weakened [H]!")
				H.apply_effect(4, WEAKEN, armor_block)
				H.forcesay(hit_appends)
			else if(H.lying)
				H.forcesay(hit_appends)

		if("disarm")
			M.do_attack_animation(H)
			add_logs(M, H, "disarmed")

			if(H.w_uniform)
				H.w_uniform.add_fingerprint(M)
			var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_sel.selecting))
			var/randn = rand(1, 100)
			if(randn <= 25)
				H.apply_effect(2, WEAKEN, H.run_armor_check(affecting, "melee"))
				playsound(H, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
				H.visible_message("[M] has pushed [H]!",
								"[M] has pushed [H]!")
				H.forcesay(hit_appends)
				return

			var/talked = 0	// BubbleWrap

			if(randn <= 60)
				//BubbleWrap: Disarming breaks a pull
				if(H.pulling)
					H.visible_message("[M] has broken [H]'s grip on [H.pulling]!")
					talked = 1
					H.stop_pulling()

				//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
				if(istype(H.l_hand, /obj/item/weapon/grab))
					var/obj/item/weapon/grab/lgrab = H.l_hand
					if(lgrab.affecting)
						H.visible_message("[M] has broken [H]'s grip on [lgrab.affecting]!")
						talked = 1
					spawn(1)
						qdel(lgrab)
				if(istype(H.r_hand, /obj/item/weapon/grab))
					var/obj/item/weapon/grab/rgrab = H.r_hand
					if(rgrab.affecting)
						H.visible_message("[M] has broken [H]'s grip on [rgrab.affecting]!")
						talked = 1
					spawn(1)
						qdel(rgrab)
				//End BubbleWrap

				if(!talked)	//BubbleWrap
					if(H.drop_item())
						H.visible_message("[M] has disarmed [H]!", \
										"[M] has disarmed [H]!")
				playsound(H, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
				return

			playsound(H, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
			H.visible_message("[M] attempted to disarm [H]!", \
							"[M] attemped to disarm [H]!")
	return

/datum/species/proc/spec_attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone, var/obj/item/organ/limb/affecting, var/hit_area, var/intent, var/obj/item/organ/limb/target_limb, target_area, var/mob/living/carbon/human/H)
	// Allows you to put in item-specific reactions based on species
	if(user != src)
		user.do_attack_animation(H)
	if((user != H) && H.check_shields(I.force, "the [I.name]"))
		return 0

	if(I.attack_verb && I.attack_verb.len)
		H.visible_message("[user] has [pick(I.attack_verb)] [H] in the [hit_area] with [I]!", \
						"[user] has [pick(I.attack_verb)] [H] in the [hit_area] with [I]!")
	else if(I.force)
		H.visible_message("[user] has attacked [H] in the [hit_area] with [I]!", \
						"[user] has attacked [H] in the [hit_area] with [I]!")
	else
		return 0

	var/armor = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].")
	if(armor >= 100)	return 0
	var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)

	apply_damage(I.force, I.damtype, affecting, armor, H)

	var/bloody = 0
	if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
		if(affecting.status == ORGAN_ORGANIC)
			I.add_blood(H)	//Make the weapon bloody, not the person.
			if(prob(I.force * 2))	//blood spatter!
				bloody = 1
				var/turf/location = H.loc
				if(istype(location, /turf/simulated))
					location.add_blood(H)
				if(get_dist(H, H) <= 1)	//people with TK won't get smeared with blood
					if(H.wear_suit)
						H.wear_suit.add_blood(H)
						H.update_inv_wear_suit(0)	//updates mob overlays to show the new blood (no refresh)
					else if(H.w_uniform)
						H.w_uniform.add_blood(H)
						H.update_inv_w_uniform(0)	//updates mob overlays to show the new blood (no refresh)
					if (H.gloves)
						var/obj/item/clothing/gloves/G = H.gloves
						G.add_blood(H)
					else
						H.add_blood(H)
						H.update_inv_gloves()	//updates on-mob overlays for bloody hands and/or bloody gloves

		switch(hit_area)
			if("head")	//Harder to score a stun but if you do it lasts a bit longer
				if(H.stat == CONSCIOUS && armor < 50)
					if(prob(I.force))
						H.visible_message("[H] has been knocked unconscious!", \
										"[H] has been knocked unconscious!")
						H.apply_effect(20, PARALYZE, armor)
					if(prob(I.force + ((100 - H.health)/2)) && H != user && I.damtype == BRUTE)
						ticker.mode.remove_revolutionary(H.mind)
						ticker.mode.remove_gangster(H.mind, exclude_bosses=1)

				if(bloody)	//Apply blood
					if(H.wear_mask)
						H.wear_mask.add_blood(H)
						H.update_inv_wear_mask(0)
					if(H.head)
						H.head.add_blood(H)
						H.update_inv_head(0)
					if(H.glasses && prob(33))
						H.glasses.add_blood(H)
						H.update_inv_glasses(0)

			if("chest")	//Easier to score a stun but lasts less time
				if(H.stat == CONSCIOUS && I.force && prob(I.force + 10))
					H.visible_message("[H] has been knocked down!", \
									"[H] has been knocked down!")
					H.apply_effect(5, WEAKEN, armor)

				if(bloody)
					if(H.wear_suit)
						H.wear_suit.add_blood(H)
						H.update_inv_wear_suit(0)
					if(H.w_uniform)
						H.w_uniform.add_blood(H)
						H.update_inv_w_uniform(0)

		if(Iforce > 10 || Iforce >= 5 && prob(33))
			H.forcesay(hit_appends)	//forcesay checks stat already.
		return

/datum/species/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone, var/mob/living/carbon/human/H)
	H.apply_damage(I.force, I.damtype)
	if(I.damtype == "brute")
		if(prob(33) && I.force && !(NOBLOOD in specflags))
			var/turf/location = H.loc
			if(istype(location, /turf/simulated))
				location.add_blood_floor(H)

	var/message_verb = ""
	if(I.attack_verb && I.attack_verb.len)
		message_verb = "[pick(I.attack_verb)]"
	else if(I.force)
		message_verb = "attacked"

	var/attack_message = "[H] has been [message_verb] with [I]."
	if(user)
		user.do_attack_animation(src)
		if(user in viewers(src, null))
			attack_message = "[user] has [message_verb] [H] with [I]!"
	if(message_verb)
		H.visible_message("[attack_message]",
		"[attack_message]")

	return

/datum/species/proc/apply_damage(var/damage, var/damagetype = BRUTE, var/def_zone = null, var/blocked, var/mob/living/carbon/human/H)
	blocked = (100-(blocked+armor))/100
	if(blocked <= 0)	return 0

	var/obj/item/organ/limb/organ = null
	if(isorgan(def_zone))
		organ = def_zone
	else
		if(!def_zone)	def_zone = ran_zone(def_zone)
		organ = H.get_organ(check_zone(def_zone))
	if(!organ)	return 0

	damage = (damage * blocked)

	switch(damagetype)
		if(BRUTE)
			H.damageoverlaytemp = 20
			if(organ.take_damage(damage*brutemod, 0))
				H.update_damage_overlays(0)
		if(BURN)
			H.damageoverlaytemp = 20
			if(organ.take_damage(0, damage*burnmod))
				H.update_damage_overlays(0)
		if(TOX)
			H.adjustToxLoss(damage * blocked)
		if(OXY)
			H.adjustOxyLoss(damage * blocked)
		if(CLONE)
			H.adjustCloneLoss(damage * blocked)
		if(STAMINA)
			H.adjustStaminaLoss(damage * blocked)

/datum/species/proc/on_hit(var/obj/item/projectile/proj_type, var/mob/living/carbon/human/H)
	// called when hit by a projectile
	switch(proj_type)
		if(/obj/item/projectile/energy/floramut) // overwritten by plants/pods
			H.show_message("The radiation beam dissipates harmlessly through your body.")
		if(/obj/item/projectile/energy/florayield)
			H.show_message("The radiation beam dissipates harmlessly through your body.")
	return

/////////////
//BREATHING//
/////////////

/datum/species/proc/breathe(var/mob/living/carbon/human/H)
	if(H.reagents.has_reagent("lexorin")) return
	if(istype(H.loc, /obj/machinery/atmospherics/unary/cryo_cell)) return

	var/datum/gas_mixture/environment = H.loc.return_air()
	var/datum/gas_mixture/breath
	// HACK NEED CHANGING LATER
	if(H.health <= config.health_threshold_crit)
		H.losebreath++

	if(H.losebreath>0) //Suffocating so do not take a breath
		H.losebreath--
		if (prob(10)) //Gasp per 10 ticks? Sounds about right.
			spawn H.emote("gasp")
		if(istype(H.loc, /obj/))
			var/obj/location_as_object = H.loc
			location_as_object.handle_internal_lifeform(H, 0)
	else
		//First, check for air from internal atmosphere (using an air tank and mask generally)
		breath = H.get_breath_from_internal(BREATH_VOLUME) // Super hacky -- TLE
		//breath = get_breath_from_internal(0.5) // Manually setting to old BREATH_VOLUME amount -- TLE

		//No breath from internal atmosphere so get breath from location
		if(!breath)
			if(isobj(H.loc))
				var/obj/location_as_object = H.loc
				breath = location_as_object.handle_internal_lifeform(H, BREATH_VOLUME)
			else if(isturf(H.loc))
				var/breath_moles = 0
				/*if(environment.return_pressure() > ONE_ATMOSPHERE)
					// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
					breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
				else*/
					// Not enough air around, take a percentage of what's there to model this properly
				breath_moles = environment.total_moles()*BREATH_PERCENTAGE

				breath = H.loc.remove_air(breath_moles)

				// Handle chem smoke effect  -- Doohl
				if(!H.has_smoke_protection())
					for(var/obj/effect/effect/chem_smoke/smoke in view(1, H))
						if(smoke.reagents.total_volume)
							smoke.reagents.reaction(H, INGEST)
							spawn(5)
								if(smoke)
									smoke.reagents.copy_to(H, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
							break // If they breathe in the nasty stuff once, no need to continue checking

		else //Still give containing object the chance to interact
			if(istype(H.loc, /obj/))
				var/obj/location_as_object = H.loc
				location_as_object.handle_internal_lifeform(H, 0)

	check_breath(breath, H)

	if(breath)
		H.loc.assume_air(breath)

/datum/species/proc/check_breath(datum/gas_mixture/breath, var/mob/living/carbon/human/H)
	if((H.status_flags & GODMODE))
		return

	if(!breath || (breath.total_moles() == 0))
		if(H.reagents.has_reagent("inaprovaline"))
			return
		if(H.health >= config.health_threshold_crit)
			if(NOBREATH in specflags)	return 1
			H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
			H.failed_last_breath = 1
		else
			H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
			H.failed_last_breath = 1

		H.throw_alert("oxy")

		return 0

	var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
	//var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now)
	var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
	var/safe_toxins_max = 0.005
	var/SA_para_min = 1
	var/SA_sleep_min = 5
	var/oxygen_used = 0
	var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*T20C)/BREATH_VOLUME

	//Partial pressure of the O2 in our breath
	var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
	// Same, but for the toxins
	var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
	// And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
	var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure // Tweaking to fit the hacky bullshit I've done with atmo -- TLE
	//var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*0.5 // The default pressure value

	if(O2_pp < safe_oxygen_min) // Too little oxygen
		if(!(NOBREATH in specflags) || (H.health <= config.health_threshold_crit))
			if(prob(20))
				spawn(0) H.emote("gasp")
			if(O2_pp > 0)
				var/ratio = safe_oxygen_min/O2_pp
				H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
				H.failed_last_breath = 1
				oxygen_used = breath.oxygen*ratio/6
			else
				H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
				H.failed_last_breath = 1
			H.throw_alert("oxy")
	else								// We're in safe limits
		H.failed_last_breath = 0
		H.adjustOxyLoss(-5)
		oxygen_used = breath.oxygen/6
		H.clear_alert("oxy")

	breath.oxygen -= oxygen_used
	breath.carbon_dioxide += oxygen_used

	//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
	if(CO2_pp > safe_co2_max && !(NOBREATH in specflags))
		if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
			H.co2overloadtime = world.time
		else if(world.time - H.co2overloadtime > 120)
			H.Paralyse(3)
			H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
			if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
				H.adjustOxyLoss(8)
		if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
			spawn(0) H.emote("cough")

	else
		H.co2overloadtime = 0

	if(Toxins_pp > safe_toxins_max && !(NOBREATH in specflags)) // Too much toxins
		var/ratio = (breath.toxins/safe_toxins_max) * 10
		//adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))	//Limit amount of damage toxin exposure can do per second
		if(H.reagents)
			H.reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
		H.throw_alert("tox_in_air")
	else
		H.clear_alert("tox_in_air")

	if(breath.trace_gases.len && !(NOBREATH in specflags))	// If there's some other shit in the air lets deal with it here.
		for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
			var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
			if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
				H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
				if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
					H.sleeping = max(H.sleeping+2, 10)
			else if(SA_pp > 0.01)	// There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
				if(prob(20))
					spawn(0) H.emote(pick("giggle", "laugh"))

	handle_breath_temperature(breath, H)

	return 1

/datum/species/proc/handle_breath_temperature(datum/gas_mixture/breath, var/mob/living/carbon/human/H) // called by human/life, handles temperatures
	if( (abs(310.15 - breath.temperature) > 50) && !(mutations_list[COLDRES] in H.dna.mutations) && !(COLDRES in specflags)) // Hot air hurts :(

		if(!(mutations_list[COLDRES] in H.dna.mutations)) // COLD DAMAGE
			switch(breath.temperature)
				if(-INFINITY to 120)
					H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head")
				if(120 to 200)
					H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head")
				if(200 to 260)
					H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head")

		if(!(HEATRES in specflags)) // HEAT DAMAGE
			switch(breath.temperature)
				if(360 to 400)
					H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head")
				if(400 to 1000)
					H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head")
				if(1000 to INFINITY)
					H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head")
/datum/species/proc/handle_environment(datum/gas_mixture/environment, var/mob/living/carbon/human/H)
	if(!environment)
		return

	var/loc_temp = H.get_temperature(environment)
	//world << "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Thermal protection: [get_thermal_protection()] - Fire protection: [thermal_protection + add_fire_protection(loc_temp)] - Heat capacity: [environment_heat_capacity] - Location: [loc] - src: [src]"

	//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
	if(H.stat != 2)
		H.stabilize_temperature_from_calories()

	//After then, it reacts to the surrounding atmosphere based on your thermal protection
	if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
		if(loc_temp < H.bodytemperature)
			//Place is colder than we are
			var/thermal_protection = H.get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
			if(thermal_protection < 1)
				H.bodytemperature += min((1-thermal_protection) * ((loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
		else
			//Place is hotter than we are
			var/thermal_protection = H.get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
			if(thermal_protection < 1)
				H.bodytemperature += min((1-thermal_protection) * ((loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)

	// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
	if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(HEATRES in specflags))
		//Body temperature is too hot.
		switch(H.bodytemperature)
			if(360 to 400)
				H.throw_alert("temp","hot",1)
				H.apply_damage(HEAT_DAMAGE_LEVEL_1*heatmod, BURN)
			if(400 to 460)
				H.throw_alert("temp","hot",2)
				H.apply_damage(HEAT_DAMAGE_LEVEL_2*heatmod, BURN)
			if(460 to INFINITY)
				H.throw_alert("temp","hot",3)
				if(H.on_fire)
					H.apply_damage(HEAT_DAMAGE_LEVEL_3*heatmod, BURN)
				else
					H.apply_damage(HEAT_DAMAGE_LEVEL_2*heatmod, BURN)

	else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !(mutations_list[COLDRES] in H.dna.mutations))
		if(!istype(H.loc, /obj/machinery/atmospherics/unary/cryo_cell))
			switch(H.bodytemperature)
				if(200 to 260)
					H.throw_alert("temp","cold",1)
					H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod, BURN)
				if(120 to 200)
					H.throw_alert("temp","cold",2)
					H.apply_damage(COLD_DAMAGE_LEVEL_2*coldmod, BURN)
				if(-INFINITY to 120)
					H.throw_alert("temp","cold",3)
					H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
		else
			H.clear_alert("temp")

	else
		H.clear_alert("temp")

	// Account for massive pressure differences.  Done by Polymorph
	// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!

	var/pressure = environment.return_pressure()
	var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
	switch(adjusted_pressure)
		if(HAZARD_HIGH_PRESSURE to INFINITY)
			if(!(HEATRES in specflags))
				H.adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
				H.throw_alert("pressure","highpressure",2)
			else
				H.clear_alert("pressure")
		if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
			H.throw_alert("pressure","highpressure",1)
		if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
			H.clear_alert("pressure")
		if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
			H.throw_alert("pressure","lowpressure",1)
		else
			if(H.dna.check_mutation(COLDRES) || (COLDRES in specflags))
				H.clear_alert("pressure")
			else
				H.adjustBruteLoss( LOW_PRESSURE_DAMAGE )
				H.throw_alert("pressure","lowpressure",2)

//////////
// FIRE //
//////////

/datum/species/proc/handle_fire(var/mob/living/carbon/human/H)
	if((HEATRES in specflags) || (NOFIRE in specflags))
		return
	if(H.fire_stacks < 0)
		H.fire_stacks++ //If we've doused ourselves in water to avoid fire, dry off slowly
		H.fire_stacks = min(0, H.fire_stacks)//So we dry ourselves back to default, nonflammable.
	if(!H.on_fire)
		return
	var/datum/gas_mixture/G = H.loc.return_air() // Check if we're standing in an oxygenless environment
	if(G.oxygen < 1)
		ExtinguishMob(H) //If there's no oxygen in the tile we're on, put out the fire
		return
	var/turf/location = get_turf(H)
	location.hotspot_expose(700, 50, 1)

/datum/species/proc/IgniteMob(var/mob/living/carbon/human/H)
	if(H.fire_stacks > 0 && !H.on_fire && !(HEATRES in specflags) && !(NOFIRE in specflags))
		H.on_fire = 1
		H.set_light(3)
		H.update_fire()

/datum/species/proc/ExtinguishMob(var/mob/living/carbon/human/H)
	if(H.on_fire)
		H.on_fire = 0
		H.fire_stacks = 0
		H.set_light(0)
		H.update_fire()

#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS

#undef HEAT_DAMAGE_LEVEL_1
#undef HEAT_DAMAGE_LEVEL_2
#undef HEAT_DAMAGE_LEVEL_3

#undef COLD_DAMAGE_LEVEL_1
#undef COLD_DAMAGE_LEVEL_2
#undef COLD_DAMAGE_LEVEL_3

#undef HEAT_GAS_DAMAGE_LEVEL_1
#undef HEAT_GAS_DAMAGE_LEVEL_2
#undef HEAT_GAS_DAMAGE_LEVEL_3

#undef COLD_GAS_DAMAGE_LEVEL_1
#undef COLD_GAS_DAMAGE_LEVEL_2
#undef COLD_GAS_DAMAGE_LEVEL_3

#undef TINT_IMPAIR
#undef TINT_BLIND