code:
/*
	Blunt/Bone wounds
*/
// TODO: well, a lot really, but i'd kill to get overlays and a bonebreaking effect like Blitz: The League, similar to electric shock skeletons
/datum/wound/blunt
	name = "Blunt Wound"
	sound_effect = 'modular_septic/sound/gore/crack1.ogg'
	base_treat_time = 6 SECONDS

	wound_type = WOUND_BLUNT
	wound_flags = (WOUND_SOUND_HINTS|WOUND_MANGLES_BONE)

/*
	Moderate - Joint dislocation
*/
/datum/wound/blunt/moderate
	name = "Joint Dislocation"
	desc = "Patient's bone has been unset from socket, causing pain and reduced motor function."
	treat_text = "Recommended application of bonesetter to affected limb, though manual relocation by applying an aggressive grab to the patient and helpfully interacting with afflicted limb may suffice."
	examine_desc = "is awkwardly jammed out of place"
	occur_text = "jerks violently and becomes unseated"

	severity = WOUND_SEVERITY_MODERATE
	viable_zones = ALL_BODYPARTS
	threshold_minimum = 25
	wound_flags = (WOUND_SOUND_HINTS)

/datum/wound/blunt/moderate/apply_wound(obj/item/bodypart/new_limb, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, add_descriptive = TRUE)
	. = ..()
	if(!.)
		return
	var/obj/item/organ/bone/bone
	for(var/thing in shuffle(new_limb.getorganslotlist(ORGAN_SLOT_BONE)))
		var/obj/item/organ/bone/possible_bone = thing
		if(possible_bone.damage >= possible_bone.low_threshold)
			continue
		bone = possible_bone
		break
	if(bone)
		bone.dislocate()
	var/final_descriptive = "A bone is dislocated!"
	// Mandible is pretty significant
	if(istype(bone, BONE_MOUTH))
		final_descriptive = "\The [bone.joint_name] is dislocated!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_danger(" [final_descriptive]"))
	qdel(src)

/*
	Severe (Hairline Fracture)
*/
/datum/wound/blunt/severe
	name = "Hairline Fracture"
	desc = "Patient's bone has suffered a crack in the foundation, causing serious pain and reduced limb functionality."
	treat_text = "Recommended light surgical application of bone gel, though a sling of medical gauze will prevent worsening situation."
	examine_desc = "appears grotesquely swollen, its attachment weakened"
	occur_text = "sprays chips of bone and develops a nasty looking bruise"

	severity = WOUND_SEVERITY_SEVERE
	sound_effect = 'modular_septic/sound/gore/crack2.ogg'
	threshold_minimum = 60
	wound_flags = (WOUND_SOUND_HINTS|WOUND_MANGLES_BONE)

/datum/wound/blunt/severe/apply_wound(obj/item/bodypart/new_limb, silent, datum/wound/old_wound, smited, add_descriptive)
	. = ..()
	if(!.)
		return
	var/obj/item/organ/bone/bone
	for(var/thing in shuffle(new_limb.getorganslotlist(ORGAN_SLOT_BONE)))
		var/obj/item/organ/bone/possible_bone = thing
		if(possible_bone.damage >= possible_bone.medium_threshold)
			continue
		bone = possible_bone
		break
	if(bone)
		bone.fracture()
	var/final_descriptive = "A bone is fractured!"
	// Skull and pelvis are pretty significant
	if(istype(bone, BONE_HEAD) || istype(bone, BONE_GROIN))
		final_descriptive = "\The [bone] is fractured!"
	// Ribs are pretty significant
	if(istype(bone, BONE_CHEST))
		final_descriptive = "\The [bone] are fractured!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_flashingdanger(" [final_descriptive]"))
	qdel(src)

/// Compound Fracture (Critical Blunt)
/datum/wound/blunt/critical
	name = "Compound Fracture"
	desc = "Patient's bones have suffered multiple gruesome fractures, causing significant pain and near uselessness of limb."
	treat_text = "Immediate binding of affected limb, followed by surgical intervention ASAP."
	examine_desc = "is mangled and pulped, seemingly held together by tissue alone"
	occur_text = "cracks apart, exposing broken bones to open air"

	severity = WOUND_SEVERITY_CRITICAL
	sound_effect = 'modular_septic/sound/gore/crack3.ogg'
	threshold_minimum = 75
	wound_flags = (WOUND_SOUND_HINTS|WOUND_MANGLES_BONE)

/datum/wound/blunt/critical/apply_wound(obj/item/bodypart/new_limb, silent, datum/wound/old_wound, smited, add_descriptive)
	. = ..()
	if(!.)
		return
	var/obj/item/organ/bone/bone
	for(var/thing in shuffle(new_limb.getorganslotlist(ORGAN_SLOT_BONE)))
		var/obj/item/organ/bone/possible_bone = thing
		if(possible_bone.damage >= possible_bone.high_threshold)
			continue
		bone = possible_bone
		break
	if(bone)
		bone.compound_fracture()
	var/final_descriptive = "A bone is shattered!"
	// Skull and pelvis are pretty significant
	if(istype(bone, BONE_HEAD) || istype(bone, BONE_GROIN))
		final_descriptive = "\The [bone] is shattered!"
	// Ribs are pretty significant
	else if(istype(bone, BONE_CHEST))
		final_descriptive = "\The [bone] are shattered!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_flashingdanger(" [final_descriptive]"))
	qdel(src)


code:
/datum/wound/nerve
	name = "Torn Nerve"
	sound_effect = 'modular_septic/sound/gore/tendon_snap2.ogg'
	base_treat_time = 3 SECONDS
	wound_type = WOUND_NERVE
	severity = WOUND_SEVERITY_CRITICAL
	desc = "Patient's tendon has been violently slashed apart, severely hindering the affected limb."
	treat_text = "Incision of the limb followed by suturing of the nerve."
	examine_desc = null
	occur_text = "is violently torn, severing a nerve"

	threshold_minimum = 100
	treatable_by = list(/obj/item/stack/medical/suture, /obj/item/stack/medical/nervemend)
	base_treat_time = 2 SECONDS
	wound_flags = (WOUND_SOUND_HINTS|WOUND_ACCEPTS_STUMP|WOUND_VISIBLE_THROUGH_CLOTHING)

/datum/wound/nerve/apply_wound(obj/item/bodypart/new_limb, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, add_descriptive = TRUE)
	. = ..()
	if(!.)
		return
	var/obj/item/organ/nerve/nerve
	for(var/thing in shuffle(new_limb.getorganslotlist(ORGAN_SLOT_NERVE)))
		var/obj/item/organ/possible_nerve = thing
		if(possible_nerve.damage >= possible_nerve.maxHealth)
			continue
		nerve = possible_nerve
		break
	var/dissection = FALSE
	if(nerve?.damage >= (nerve?.maxHealth * 0.5))
		dissection = TRUE
	if(nerve)
		nerve.tear()
	var/final_descriptive = "A nerve is [dissection ? "torn" : "damaged"]!"
	// Sciatic is pretty significant
	if(istype(nerve, NERVE_R_LEG) || istype(nerve, NERVE_L_LEG))
		final_descriptive = "\The [nerve] is [dissection ? "torn" : "damaged"]!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_flashingdanger(" [final_descriptive]"))
	qdel(src)

repo_name: AnalWerewolf/sundown

license: mit


code:
/*
	Britification
*/
/datum/wound/teeth
	name = "Dental Avulsion"
	desc = "Patient's teeth have been violently ripped off due to blunt trauma."
	occur_text = "has it's teeth sail off in an arc"
	sound_effect = list('modular_septic/sound/gore/trauma1.ogg', \
					'modular_septic/sound/gore/trauma2.ogg', \
					'modular_septic/sound/gore/trauma3.ogg')

	severity = WOUND_SEVERITY_TRIVIAL
	viable_zones = ALL_BODYPARTS

	threshold_minimum = 20
	wound_type = WOUND_TEETH
	wound_flags = (WOUND_SOUND_HINTS)

/datum/wound/teeth/can_afflict(obj/item/bodypart/new_limb, datum/wound/old_wound)
	. = ..()
	if(!.)
		return
	if(!new_limb.get_teeth_amount())
		return

/datum/wound/teeth/apply_wound(obj/item/bodypart/new_limb, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, add_descriptive = TRUE)
	. = ..()
	if(!.)
		return
	if(!new_limb.max_teeth)
		qdel(src)
		return
	var/final_descriptive = "Teeth sail off in an arc!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_danger(" [final_descriptive]"))
	new_limb.knock_out_teeth(rand(1,4), pick(GLOB.alldirs))
	qdel(src)


code:
/datum/wound/tendon
	name = "Torn Tendon"
	sound_effect = 'modular_septic/sound/gore/tendon_snap1.wav'
	base_treat_time = 3 SECONDS
	wound_type = WOUND_TENDON
	severity = WOUND_SEVERITY_CRITICAL
	desc = "Patient's tendon has been violently slashed apart, severely hindering the affected limb."
	treat_text = "Incision of the limb followed by suturing of the tendon."
	examine_desc = null
	occur_text = "is violently torn, severing a tendon"

	threshold_minimum = 60
	treatable_by = list(/obj/item/stack/medical/suture, /obj/item/stack/medical/nervemend)
	wound_flags = (WOUND_SOUND_HINTS|WOUND_ACCEPTS_STUMP|WOUND_VISIBLE_THROUGH_CLOTHING)

/datum/wound/tendon/apply_wound(obj/item/bodypart/new_limb, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, add_descriptive = TRUE)
	. = ..()
	if(!.)
		return
	var/obj/item/organ/tendon/tendon
	for(var/thing in shuffle(new_limb.getorganslotlist(ORGAN_SLOT_TENDON)))
		var/obj/item/organ/possible_tendon = thing
		if(possible_tendon.damage >= possible_tendon.maxHealth)
			continue
		tendon = possible_tendon
		break
	var/dissection = FALSE
	if(tendon?.damage >= (tendon?.maxHealth * 0.5))
		dissection = TRUE
	if(tendon)
		tendon.tear()
	var/final_descriptive = "A tendon is [dissection ? "torn" : "damaged"]!"
	// Achilles tendon is pretty significant
	if(istype(tendon, TENDON_R_FOOT) || istype(tendon, TENDON_L_FOOT))
		final_descriptive = "\The [tendon] is [dissection ? "torn" : "damaged"]!"
	if(victim)
		if(sound_effect)
			playsound(new_limb.owner, pick(sound_effect), 70 + 20 * severity, TRUE)
		if(add_descriptive)
			SEND_SIGNAL(victim, COMSIG_CARBON_ADD_TO_WOUND_MESSAGE, span_flashingdanger(" [final_descriptive]"))
	qdel(src)


code:
/**
 * scars are cosmetic datums that are assigned to bodyparts once they recover from wounds. Each wound type and severity have their own descriptions for what the scars
 * look like, and then each body part has a list of "specific locations" like your elbow or wrist or wherever the scar can appear, to make it more interesting than "right arm"
 *
 *
 * Arguments:
 * *
 */
/datum/scar
	var/obj/item/bodypart/limb
	var/mob/living/carbon/victim
	/// The severity of the scar, derived from the worst severity a wound was at before it was healed (see: slashes), determines how visible/bold the scar description is
	var/severity
	/// The description of the scar for examining
	var/description
	/// A string detailing the specific part of the bodypart the scar is on, for fluff purposes. See [/datum/scar/proc/generate]
	var/precise_location

	/// These scars are assumed to come from changeling disguises, rather than from persistence or wounds. As such, they are deleted by dropping changeling disguises, and are ignored by persistence
	var/fake=FALSE
	/// How many tiles away someone can see this scar, goes up with severity. Clothes covering this limb will decrease visibility by 1 each, except for the head/face which is a binary "is mask obscuring face" check
	var/visibility = 2
	/// Whether this scar can actually be covered up by clothing
	var/coverable = TRUE
	/// Obviously, scars that describe damaged flesh wouldn't apply to a skeleton (in some cases like bone wounds, there can be different descriptions for skeletons and fleshy humanoids)
	var/biology = BIO_FLESH_BONE
	/// If we're a persistent scar or may become one, we go in this character slot
	var/persistent_character_slot = 0

/datum/scar/Destroy(force, ...)
	if(limb)
		LAZYREMOVE(limb.scars, src)
	if(victim)
		LAZYREMOVE(victim.all_scars, src)
	limb = null
	victim = null
	. = ..()

/**
 * generate() is used to actually fill out the info for a scar, according to the limb and wound it is provided.
 *
 * After creating a scar, call this on it while targeting the scarred bodypart with a given wound to apply the scar.
 *
 * Arguments:
 * * BP- The bodypart being targeted
 * * W- The wound being used to generate the severity and description info
 * * add_to_scars- Should always be TRUE unless you're just storing a scar for later usage, like how cuts want to store a scar for the highest severity of cut, rather than the severity when the wound is fully healed (probably demoted to moderate)
 */
/datum/scar/proc/generate(obj/item/bodypart/BP, datum/wound/W, add_to_scars=TRUE)
	if(!W.scar_keyword)
		return
	limb = BP
	RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone)

	severity = W.severity
	if(limb.owner)
		victim = limb.owner
		persistent_character_slot = victim.mind?.original_character_slot_index
	if(add_to_scars)
		LAZYADD(limb.scars, src)
		if(victim)
			LAZYADD(victim.all_scars, src)

	biology = victim?.get_biological_state() || BIO_FLESH_BONE

	if(biology == BIO_JUST_BONE)
		description = pick_list(BONE_SCAR_FILE, W.scar_keyword) || "general disfigurement"
	else // no specific support for flesh w/o bone scars since it's not really useful
		description = pick_list(FLESH_SCAR_FILE, W.scar_keyword) || "general disfigurement"

	precise_location = pick_list_replacements(SCAR_LOC_FILE, limb.body_zone)
	switch(W.severity)
		if(WOUND_SEVERITY_MODERATE)
			visibility = 2
		if(WOUND_SEVERITY_SEVERE)
			visibility = 3
		if(WOUND_SEVERITY_CRITICAL)
			visibility = 5
		if(WOUND_SEVERITY_LOSS)
			visibility = 7
			precise_location = "amputation"

/// Used when we finalize a scar from a healing cut
/datum/scar/proc/lazy_attach(obj/item/bodypart/BP, datum/wound/W)
	LAZYADD(BP.scars, src)
	if(BP.owner)
		victim = BP.owner
		LAZYADD(victim.all_scars, src)

/// Used to "load" a persistent scar
/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE, biology=BIO_FLESH_BONE, char_slot)
	if(!BP.is_organic_limb())
		qdel(src)
		return

	limb = BP
	RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone)
	if(limb.owner)
		victim = limb.owner
		if(victim.get_biological_state() != biology)
			qdel(src)
			return
		LAZYADD(victim.all_scars, src)

	src.severity = severity
	src.biology = biology
	persistent_character_slot = char_slot
	LAZYADD(limb.scars, src)

	src.description = description
	precise_location = specific_location
	switch(severity)
		if(WOUND_SEVERITY_MODERATE)
			visibility = 2
		if(WOUND_SEVERITY_SEVERE)
			visibility = 3
		if(WOUND_SEVERITY_CRITICAL)
			visibility = 5
		if(WOUND_SEVERITY_LOSS)
			visibility = 7
	return src

/datum/scar/proc/limb_gone()
	SIGNAL_HANDLER
	qdel(src)

/// What will show up in examine_more() if this scar is visible
/datum/scar/proc/get_examine_description(mob/viewer)
	if(!victim || !is_visible(viewer))
		return

	var/msg = "[victim.p_they(TRUE)] [victim.p_have()] [description] on [victim.p_their()] [precise_location]."
	switch(severity)
		if(WOUND_SEVERITY_MODERATE)
			msg = span_tinynoticeital("[msg]")
		if(WOUND_SEVERITY_SEVERE)
			msg = span_smallnoticeital("[msg]")
		if(WOUND_SEVERITY_CRITICAL)
			msg = span_smallnoticeital("[msg]")
		if(WOUND_SEVERITY_LOSS)
			msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format
			msg = span_notice("[msg]")
	return "\t[msg]"

/// Whether a scar can currently be seen by the viewer
/datum/scar/proc/is_visible(mob/viewer)
	if(!victim || !viewer)
		return
	if(get_dist(viewer, victim) > visibility)
		return

	if(!ishuman(victim) || isobserver(viewer) || victim == viewer)
		return TRUE

	var/mob/living/carbon/human/human_victim = victim
	if(istype(limb, /obj/item/bodypart/head))
		if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE)))
			return FALSE
	else if(limb.scars_covered_by_clothes)
		var/num_covers = LAZYLEN(human_victim.clothingonpart(limb))
		if(num_covers + get_dist(viewer, victim) >= visibility)
			return FALSE

	return TRUE

/// Used to format a scar to save for either persistent scars, or for changeling disguises
/datum/scar/proc/format()
	return "[SCAR_CURRENT_VERSION]|[limb.body_zone]|[description]|[precise_location]|[severity]|[biology]|[persistent_character_slot]"

/// Used to format a scar to save in preferences for persistent scars
/datum/scar/proc/format_amputated(body_zone)
	description = pick_list(FLESH_SCAR_FILE, "dismember")
	return "[SCAR_CURRENT_VERSION]|[body_zone]|[description]|amputated|[WOUND_SEVERITY_LOSS]|[BIO_FLESH_BONE]|[persistent_character_slot]"


code:
/proc/healthscan(mob/user, mob/living/M, mode = SCANNER_VERBOSE, advanced = FALSE)
	if(user.incapacitated())
		return

	if(user.is_blind())
		to_chat(user, "The scanner doesn't support braille. Damn.")
		return

	// the final list of strings to render
	var/render_list = list()

	// Damage specifics
	var/is_advanced = (advanced || M.has_reagent(/datum/reagent/inverse/technetium))
	var/oxy_loss = M.getOxyLoss()
	var/tox_loss = M.getToxLoss()
	var/fire_loss = M.getFireLoss()
	var/brute_loss = M.getBruteLoss()
	var/mob_status = (M.stat == DEAD ? "Braindead." : "[round(M.health/M.maxHealth,0.01)*100]%")

	if(HAS_TRAIT(M, TRAIT_FAKEDEATH) && !is_advanced)
		mob_status = "Braindead."

	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(H.undergoing_cardiac_arrest() && H.stat < DEAD)
			render_list += "Subject suffering cardiac arrest: Apply defibrillation or other electric shock immediately!\n"

	render_list += "Analyzing results for [M]:\n"
	render_list += "Brain activity: [mob_status]\n"
	var/overall_damage = M.get_physical_damage()
	if(overall_damage  <= 10)
		overall_damage = "[overall_damage]"
	else if(overall_damage >= 50)
		overall_damage = "[overall_damage]"
	render_list += "Accumulated damage: [overall_damage]\n"

	// Brain not added to carbon/human check because it's funny to get to bully simple mobs
	if(!M.getorganslot(ORGAN_SLOT_BRAIN))
		render_list += "Subject is anencephalic and lacks higher brain function.\n"

	// Husk detection
	if(is_advanced && HAS_TRAIT_FROM(M, TRAIT_HUSK, BURN))
		render_list += "Subject has been husked by severe burns.\n"
	else if (is_advanced && HAS_TRAIT_FROM(M, TRAIT_HUSK, CHANGELING_DRAIN))
		render_list += "Subject has been husked by dessication.\n"
	else if(HAS_TRAIT(M, TRAIT_HUSK))
		render_list += "Subject has been husked.\n"

	// Disfigurement detection
	if(is_advanced && HAS_TRAIT_FROM(M, TRAIT_DISFIGURED, BRUTE))
		render_list += "Subject has been disfigured by severe brute trauma.\n"
	else if(is_advanced && HAS_TRAIT_FROM(M, TRAIT_DISFIGURED, BURN))
		render_list += "Subject has been disfigured by severe burns.\n"
	else if(is_advanced && HAS_TRAIT_FROM(M, TRAIT_DISFIGURED, GERM_LEVEL))
		render_list += "Subject has been disfigured by necrosis.\n"
	else if(HAS_TRAIT(M, TRAIT_DISFIGURED))
		render_list += "Subject has been disfigured.\n"

	// Damage descriptions
	if(brute_loss >= 10)
		render_list += "[brute_loss >= 50 ? "Severe" : "Minor"] physical trauma detected.\n"
	if(fire_loss >= 10)
		render_list += "[fire_loss >= 50 ? "Severe" : "Minor"] burn damage detected.\n"
	if(oxy_loss >= 10)
		render_list += "[oxy_loss >= 50 ? "Severe" : "Minor"] oxygen deprivation detected.\n"
	if(tox_loss >= 10)
		render_list += "[tox_loss >= 50 ? "Severe" : "Minor"] amount of toxin damage detected.\n"
	if(M.getCloneLoss())
		if(is_advanced)
			render_list += "Cellular Damage Level: [M.getCloneLoss()].\n"
		else
			render_list += "Subject appears to have [M.getCloneLoss() >= 30 ? "severe" : "minor"] cellular damage.\n"
	if(M.getStaminaLoss())
		if(is_advanced)
			render_list += "Fatigue Level: [M.getStaminaLoss()/M.maxHealth * 100]%.\n"
		else
			render_list += "Subject appears to be suffering from fatigue.\n"

	if(iscarbon(M))
		var/mob/living/carbon/C = M
		if(LAZYLEN(C.get_traumas()))
			var/list/trauma_text = list()
			for(var/thing in C.get_traumas())
				var/datum/brain_trauma/B = thing
				var/trauma_desc = ""
				switch(B.resilience)
					if(TRAUMA_RESILIENCE_SURGERY)
						trauma_desc += "severe "
					if(TRAUMA_RESILIENCE_LOBOTOMY)
						trauma_desc += "deep-rooted "
					if(TRAUMA_RESILIENCE_WOUND)
						trauma_desc += "trauma-derived "
					if(TRAUMA_RESILIENCE_MAGIC, TRAUMA_RESILIENCE_ABSOLUTE)
						trauma_desc += "permanent "
				trauma_desc += B.scan_desc
				trauma_text += trauma_desc
			if(LAZYLEN(trauma_text))
				render_list += "Cerebral traumas detected: subject appears to be suffering from [english_list(trauma_text)].\n"
		if(length(C.quirks))
			render_list += "Subject Major Disabilities: [C.get_quirk_string(FALSE, CAT_QUIRK_MAJOR_DISABILITY)].\n"
			if(is_advanced)
				render_list += "Subject Minor Disabilities: [C.get_quirk_string(FALSE, CAT_QUIRK_MINOR_DISABILITY)].\n"

	if (M.radiation)
		if(is_advanced)
			render_list += "Radiation Level: [M.radiation]%.\n"
		else
			render_list += "Subject is irradiated.\n"

	if(is_advanced && M.hallucinating())
		render_list += "Subject is hallucinating.\n"

	if(iscarbon(M) && mode == SCANNER_VERBOSE)
		var/mob/living/carbon/C = M
		var/list/damaged = (C.get_damaged_bodyparts(TRUE, TRUE) | C.get_infected_bodyparts())
		// Body part damage/infection report
		if(length(damaged) > 0 || oxy_loss > 0 || tox_loss > 0 || fire_loss > 0)
			var/dmgreport = "Bodypart status\

\

\
							Damage	\
							Brute	\
							Burn	\
							Toxin	\
							Suffocation	\
							Germ	\

\

\
							Overall	\
							[CEILING(brute_loss,1)]	\
							[CEILING(fire_loss,1)]	\
							[CEILING(tox_loss,1)]	\
							[CEILING(oxy_loss,1)]	\
								\

"

			for(var/o in damaged)
				var/obj/item/bodypart/org = o //head, left arm, right arm, etc.
				dmgreport += "
[capitalize_like_old_man(org.name)]	\
								[CEILING(org.brute_dam,1)]	\
								[CEILING(org.burn_dam,1)]	\
									\
									\
								[CEILING(org.germ_level/INFECTION_LEVEL_THREE*100,1)]%	\

"
			dmgreport += "
"
			render_list += dmgreport // tables do not need extra linebreak

		// Organ damage report
		if (LAZYLEN(C.internal_organs))
			var/render = FALSE
			var/toReport = "Organ status\

\

\
				Organ	\
				[(is_advanced || C.has_reagent(/datum/reagent/inverse/technetium)) ? "Damage	" : ""]\
				Status	\
				Germ	\

"

			for(var/thing in C.internal_organs)
				var/obj/item/organ/organ = thing
				var/status = ""
				if(organ.is_necrotic())
					status = "Necrotic"
				else if(organ.is_dead())
					status = "Destroyed"
				else if(organ.is_failing())
					status = "Failing"
				else if(organ.damage >= organ.high_threshold)
					status = "Severely Damaged"
				else if(organ.damage >= organ.low_threshold)
					status = "Mildly Damaged"
				else if(organ.damage && is_advanced)
					status = "Minorly Damaged"
				if (status != "")
					render = TRUE
					toReport += "
\
						[capitalize_like_old_man(organ.name)]:	\
						[(is_advanced || C.has_reagent(/datum/reagent/inverse/technetium)) ? "[CEILING(organ.damage,1)]	" : ""]\
						[status]	\
						[CEILING(organ.germ_level/INFECTION_LEVEL_THREE*100,1)]%	\

"

			if (render)
				render_list += toReport + "
" // tables do not need extra linebreak

	if(ishuman(M))
		var/mob/living/carbon/human/the_dude = M
		var/datum/species/the_dudes_species = the_dude.dna.species
		if (!(NOBLOOD in the_dudes_species.species_traits))
			if(!the_dude.getorganslot(ORGAN_SLOT_HEART))
				render_list += "Subject lacks a heart.\n"
			if(!the_dude.getorganslot(ORGAN_SLOT_SPLEEN))
				render_list += "Subject lacks a spleen.\n"
		var/list/lungs = the_dude.getorganslotlist(ORGAN_SLOT_LUNGS)
		var/lacklungs = max(0, 2 - length(lungs))
		if (!(TRAIT_NOBREATH in the_dudes_species.species_traits))
			switch(lacklungs)
				if(1)
					render_list += "Subject lacks one of [the_dude.p_their()] lungs.\n"
				if(2)
					render_list += "Subject lacks both lungs.\n"
		if (!(TRAIT_NOMETABOLISM in the_dudes_species.species_traits))
			if(!the_dude.getorganslot(ORGAN_SLOT_LIVER))
				render_list += "Subject lacks a liver.\n"
			var/list/kidneys = the_dude.getorganslotlist(ORGAN_SLOT_KIDNEYS)
			var/lackkidneys = max(0, 2 - length(kidneys))
			switch(lackkidneys)
				if(1)
					render_list += "Subject lacks one of [the_dude.p_their()] kidneys.\n"
				if(2)
					render_list += "Subject lacks both kidneys.\n"
		if (!(NOSTOMACH in the_dudes_species.species_traits) && !the_dude.getorganslot(ORGAN_SLOT_STOMACH))
			render_list += "Subject lacks a stomach.\n"

		// Ear status
		var/list/ears = the_dude.getorganslotlist(ORGAN_SLOT_EARS)
		var/lackears = max(0, 2 - length(ears))
		var/ear_message = "\nSubject lacks both ears.\n"
		if(length(ears))
			ear_message = "\n"
			if(lackears)
				ear_message += "Subject lacks one of [the_dude.p_their()] ears.\n"
			if(is_advanced && HAS_TRAIT_FROM(the_dude, TRAIT_DEAF, GENETIC_MUTATION))
				ear_message += "Subject is genetically deaf.\n"
			else if(is_advanced && HAS_TRAIT_FROM(the_dude, TRAIT_DEAF, EAR_DAMAGE))
				ear_message += "Subject is deaf from ear damage.\n"
			else if(HAS_TRAIT(the_dude, TRAIT_DEAF))
				ear_message += "Subject is deaf.\n"
			else
				var/ear_maxhealth = 0
				var/ear_damage = 0
				var/ear_deaf = 0
				for(var/thing in ears)
					var/obj/item/organ/ears/ear = thing
					ear_maxhealth += ear.maxHealth
					if(ear.is_dead())
						ear_damage += ear.maxHealth
						ear_deaf += 1
					else
						ear_damage += ear.damage
						ear_deaf += ear.deaf
				if(ear_damage)
					ear_message += "Subject has [ear_damage >= ear_maxhealth ? "permanent": "mild"] ear damage.\n"
				if(ear_deaf >= length(ears))
					ear_message += "Subject is [ear_damage >= ear_maxhealth ? "permanently": "temporarily"] deaf.\n"
		if(ear_message && (ear_message != "\n"))
			render_list += ear_message

		// Eye status
		var/list/eyes = the_dude.getorganslotlist(ORGAN_SLOT_EYES)
		var/lackeyes = max(0, 2 - length(eyes))
		var/eye_message = "\nSubject lacks both eyes.\n"
		if(length(eyes))
			eye_message = "\n"
			if(lackeyes)
				ear_message += "Subject lacks one of [the_dude.p_their()] eyes.\n"
			if(the_dude.is_blind())
				eye_message += "Subject is blind.\n"
			if(HAS_TRAIT(the_dude, TRAIT_NEARSIGHT))
				eye_message += "Subject is nearsighted.\n"
			var/eye_damage = 0
			for(var/thing in eyes)
				var/obj/item/organ/eyes/eye = thing
				eye_damage += eye.damage
			if(eye_damage >= 30)
				eye_message += "Subject has severe eye damage.\n"
			else if(eye_damage >= 20)
				eye_message += "Subject has significant eye damage.\n"
			else if(eye_damage)
				eye_message += "Subject has minor eye damage.\n"
		if(eye_message && (eye_message != "\n"))
			render_list += eye_message

		// GENITALS AHHHHHHH
		var/list/peepee_organs = list(ORGAN_SLOT_PENIS, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_VAGINA, ORGAN_SLOT_WOMB, ORGAN_SLOT_BREASTS)
		for(var/peepee in peepee_organs)
			if(the_dude.should_have_genital(peepee) && !the_dude.getorganslot(peepee))
				render_list += "Subject lacks \a [peepee].\n"

		// Genetic damage
		if(is_advanced && the_dude.has_dna())
			render_list += "Genetic Stability: [the_dude.dna.stability]%.\n"

		// Species and body temperature
		var/datum/species/S = the_dude.dna.species
		var/mutant = (the_dude.dna.check_mutation(HULK) \
			|| S.mutantlungs != initial(S.mutantlungs) \
			|| S.mutantbrain != initial(S.mutantbrain) \
			|| S.mutantheart != initial(S.mutantheart) \
			|| S.mutantheart != initial(S.mutantheart) \
			|| S.mutanteyes != initial(S.mutanteyes) \
			|| S.mutantears != initial(S.mutantears) \
			|| S.mutanthands != initial(S.mutanthands) \
			|| S.mutanttongue != initial(S.mutanttongue) \
			|| S.mutantliver != initial(S.mutantliver) \
			|| S.mutantkidneys != initial(S.mutantkidneys) \
			|| S.mutantstomach != initial(S.mutantstomach) \
			|| S.mutantappendix != initial(S.mutantappendix) \
			|| S.flying_species != initial(S.flying_species) \
			|| S.reagent_processing != initial(S.reagent_processing) \
			|| S.limbs_icon != initial(S.limbs_icon))

		render_list += "Species: [S.name][mutant ? "-derived mutant" : ""]\n"
		render_list += "Core temperature: [round(the_dude.coretemperature-T0C,0.1)] °C ([round(the_dude.coretemperature*1.8-459.67,0.1)] °F)\n"
	render_list += "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n"

	// Time of death
	if(M.tod && (M.stat == DEAD || (HAS_TRAIT(M, TRAIT_FAKEDEATH) && !is_advanced)))
		render_list += "Time of Death: [M.tod]\n"
		var/tdelta = round(world.time - M.timeofdeath)
		render_list += "Subject died [DisplayTimeText(tdelta)] ago.\n"

	// Wounds
	if(iscarbon(M))
		var/mob/living/carbon/C = M
		var/list/wounded_parts = C.get_wounded_bodyparts()
		for(var/i in wounded_parts)
			var/obj/item/bodypart/wounded_part = i
			render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]"
			for(var/k in wounded_part.wounds)
				var/datum/wound/W = k
				render_list += "
Type: [W.name]\nSeverity: [W.severity_text()]\nRecommended Treatment: [W.treat_text]
\n" // less lines than in woundscan() so we don't overload people trying to get basic med info
			render_list += ""

	for(var/thing in M.diseases)
		var/datum/disease/D = thing
		if(!(D.visibility_flags & HIDDEN_SCANNER))
			render_list += "\
			Warning: [D.form] detected\n\

\
			Name: [D.name].\nType: [D.spread_text].\n\
			Stage: [D.stage]/[D.max_stages].\n\
			Possible Cure: [D.cure_text]\

\
			" // divs do not need extra linebreak

	// Blood and pulse
	if(M.has_dna())
		var/mob/living/carbon/C = M
		var/blood_id = C.get_blood_id()
		if(blood_id)
			if(ishuman(C))
				var/mob/living/carbon/human/H = C
				if(H.is_bleeding())
					render_list += "Subject is bleeding!\n"
			var/blood_type = C.dna.blood_type
			if(blood_id != /datum/reagent/blood) // special blood substance
				var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
				blood_type = R ? R.name : blood_id
			render_list += "Blood type: [blood_type]\n"
			var/pulse = C.get_pulse(is_advanced ? GETPULSE_ADVANCED : GETPULSE_BASIC)
			render_list += "Pulse: [pulse]\n"
			var/normal_volume = GET_EFFECTIVE_BLOOD_VOL(BLOOD_VOLUME_NORMAL, C.total_blood_req)
			render_list += "Ideal blood volume: [normal_volume]cl\n"
			var/okay_volume = GET_EFFECTIVE_BLOOD_VOL(BLOOD_VOLUME_OKAY, C.total_blood_req)
			var/safe_volume = GET_EFFECTIVE_BLOOD_VOL(BLOOD_VOLUME_SAFE, C.total_blood_req)
			var/blood_circulation = C.get_blood_circulation()
			var/blood_percent =  FLOOR((blood_circulation/normal_volume)*100, 1)
			var/blood_oxygenation = C.get_blood_oxygenation()
			var/oxygenation_percent = FLOOR((blood_oxygenation/normal_volume)*100, 1)
			if(blood_circulation <= safe_volume && blood_circulation >= okay_volume)
				render_list += "Blood circulation: LOW [blood_percent]%, [blood_circulation]cl\n"
			else if(blood_circulation < okay_volume)
				render_list += "Blood circulation: CRITICAL [blood_percent]%, [blood_circulation]cl\n"
			else
				render_list += "Blood circulation: [blood_percent]%, [blood_circulation]cl\n"
			if(blood_oxygenation <= safe_volume && blood_oxygenation >= okay_volume)
				render_list += "Blood oxygenation: LOW [oxygenation_percent]%, [blood_oxygenation]cl\n"
			else if(blood_oxygenation < okay_volume)
				render_list += "Blood oxygenation: CRITICAL [oxygenation_percent]%, [blood_oxygenation]cl\n"
			else
				render_list += "Blood oxygenation: [oxygenation_percent]%, [blood_oxygenation]cl\n"

	if(iscarbon(M))
		var/mob/living/carbon/C = M
		var/cyberimp_detect
		for(var/obj/item/organ/cyberimp/CI in C.internal_organs)
			//if(CI.status == ORGAN_ROBOTIC && !CI.syndicate_implant) //SEPTIC EDIT REMOVAL
			//SEPTIC EDIT BEGIN
			if(CI.status == ORGAN_ROBOTIC && !CI.scanner_hidden)
			//SEPTIC EDIT END
				cyberimp_detect += "[!cyberimp_detect ? "[CI.get_examine_string(user)]" : ", [CI.get_examine_string(user)]"]"
		if(cyberimp_detect)
			render_list += "Detected cybernetic modifications:\n"
			render_list += "[cyberimp_detect]\n"

	to_chat(user, jointext(render_list, ""), trailing_newline = FALSE) // we handled the last
 so we don't need handholding

/proc/chemscan(mob/living/user, mob/living/M)
	if(user.incapacitated())
		return

	if(user.is_blind())
		to_chat(user, "You realize that your scanner has no accessibility support for the blind!")
		return

	if(istype(M) && M.reagents)
		var/render_list = list()
		if(M.reagents.reagent_list.len)
			render_list += "Subject contains the following reagents in their blood:\n"
			for(var/r in M.reagents.reagent_list)
				var/datum/reagent/reagent = r
				if(reagent.chemical_flags & REAGENT_INVISIBLE) //Don't show hidden chems on scanners
					continue
				render_list += "[round(reagent.volume, 0.001)] units of [reagent.name][reagent.overdosed ? " - OVERDOSING" : "."]\n"
		else
			render_list += "Subject contains no reagents in their blood.\n"
		var/obj/item/organ/stomach/belly = M.getorganslot(ORGAN_SLOT_STOMACH)
		if(belly)
			if(belly.reagents.reagent_list.len)
				render_list += "Subject contains the following reagents in their stomach:\n"
				for(var/bile in belly.reagents.reagent_list)
					var/datum/reagent/bit = bile
					if(bit.chemical_flags & REAGENT_INVISIBLE) //Don't show hidden chems on scanners
						continue
					if(!belly.food_reagents[bit.type])
						render_list += "[round(bit.volume, 0.001)] units of [bit.name][bit.overdosed ? " - OVERDOSING" : "."]\n"
					else
						var/bit_vol = bit.volume - belly.food_reagents[bit.type]
						if(bit_vol > 0)
							render_list += "[round(bit_vol, 0.001)] units of [bit.name][bit.overdosed ? " - OVERDOSING" : "."]\n"
			else
				render_list += "Subject contains no reagents in their stomach.\n"

		if(LAZYLEN(M.mind?.active_addictions))
			render_list += "Subject is addicted to the following types of drug:\n"
			for(var/datum/addiction/addiction_type as anything in M.mind.active_addictions)
				render_list += "[initial(addiction_type.name)]\n"
		else
			render_list += "Subject is not addicted to any types of drug.\n"

		if(M.has_status_effect(/datum/status_effect/eigenstasium))
			render_list += "Subject is temporally unstable. Stabilising agent is recommended to reduce disturbances.\n"

		to_chat(user, jointext(render_list, ""), trailing_newline = FALSE) // we handled the last
 so we don't need handholding


code:
/obj/item/disk
	carry_weight = 0.2

/obj/item/disk/surgery
	name = "Surgery Procedure Disk"
	desc = "A disk that contains advanced surgery procedures, must be loaded into an Operating Console."
	icon_state = "datadisk1"
	custom_materials = list(/datum/material/iron=300, /datum/material/glass=100)
	var/list/surgeries

/obj/item/disk/surgery/debug
	name = "Debug Surgery Disk"
	desc = "A disk that contains all existing surgery procedures."
	icon_state = "datadisk1"
	custom_materials = list(/datum/material/iron=300, /datum/material/glass=100)

/obj/item/disk/surgery/debug/Initialize()
	. = ..()
	surgeries = list()
	var/list/req_tech_surgeries = subtypesof(/datum/surgery_step)
	for(var/i in req_tech_surgeries)
		var/datum/surgery_step/beep = i
		if(initial(beep.requires_tech))
			surgeries += beep


code:
/proc/find_cauterizing_tool(list/item_list)
	for(var/thing in item_list)
		var/obj/item/item = thing
		if(item.tool_behaviour == TOOL_CAUTERY || item.get_temperature() > 300)
			return item
	return FALSE

/proc/get_surgery_location_modifier(mob/M)
	var/turf/turf_loc = get_turf(M)
	if(locate(/obj/structure/table/optable, turf_loc))
		return 1
	else if(locate(/obj/machinery/stasis, turf_loc))
		return 0.9
	else if(locate(/obj/structure/table, turf_loc))
		return 0.8
	else if(locate(/obj/structure/bed, turf_loc))
		return 0.7
	else
		return 0.6

/proc/get_surgery_probability_multiplier(datum/surgery_step/step, mob/target, mob/user)
	var/probability = get_surgery_location_modifier(target)
	//self-surgery is hard
	if(target == user)
		probability *= 0.75
	return probability * step.success_multiplier

/proc/get_location_accessible(mob/M, location)
	var/covered_locations = 0 //based on body_parts_covered
	var/face_covered = 0 //based on flags_inv
	var/eyesmouth_covered = 0 //based on flags_cover
	if(iscarbon(M))
		var/mob/living/carbon/C = M
		for(var/obj/item/clothing/I in list(C.back, C.wear_mask, C.head))
			covered_locations |= I.body_parts_covered
			face_covered |= I.flags_inv
			eyesmouth_covered |= I.flags_cover
		if(ishuman(C))
			var/mob/living/carbon/human/H = C
			for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.ears, H.ears_extra))
				covered_locations |= I.body_parts_covered
				face_covered |= I.flags_inv
				eyesmouth_covered |= I.flags_cover

	switch(location)
		if(BODY_ZONE_HEAD)
			if(covered_locations & HEAD)
				return FALSE
		if(BODY_ZONE_PRECISE_L_EYE, BODY_ZONE_PRECISE_R_EYE)
			if(covered_locations & EYES || face_covered & HIDEEYES || eyesmouth_covered & GLASSESCOVERSEYES)
				return FALSE
		if(BODY_ZONE_PRECISE_FACE)
			if(covered_locations & FACE || face_covered & HIDEFACE)
				return FALSE
		if(BODY_ZONE_PRECISE_MOUTH)
			if(covered_locations & JAW || face_covered & HIDEFACE || eyesmouth_covered & MASKCOVERSMOUTH || eyesmouth_covered & HEADCOVERSMOUTH)
				return FALSE
		if(BODY_ZONE_CHEST)
			if(covered_locations & CHEST)
				return FALSE
		if(BODY_ZONE_PRECISE_GROIN)
			if(covered_locations & GROIN)
				return FALSE
		if(BODY_ZONE_L_ARM)
			if(covered_locations & ARM_LEFT)
				return FALSE
		if(BODY_ZONE_R_ARM)
			if(covered_locations & ARM_RIGHT)
				return FALSE
		if(BODY_ZONE_L_LEG)
			if(covered_locations & LEG_LEFT)
				return FALSE
		if(BODY_ZONE_R_LEG)
			if(covered_locations & LEG_RIGHT)
				return FALSE
		if(BODY_ZONE_PRECISE_L_HAND)
			if(covered_locations & HAND_LEFT)
				return FALSE
		if(BODY_ZONE_PRECISE_R_HAND)
			if(covered_locations & HAND_RIGHT)
				return FALSE
		if(BODY_ZONE_PRECISE_L_FOOT)
			if(covered_locations & FOOT_LEFT)
				return FALSE
		if(BODY_ZONE_PRECISE_R_FOOT)
			if(covered_locations & FOOT_RIGHT)
				return FALSE

	return TRUE

/proc/spread_germs_to_bodypart(obj/item/bodypart/bodypart, mob/living/carbon/human/user, obj/item/tool)
	. = FALSE
	if(!istype(user) || !istype(bodypart) || !istype(bodypart.owner) || bodypart.is_robotic_limb())
		return

	//Germs from the surgeon
	var/our_germ_level = user.germ_level
	if(user.gloves)
		our_germ_level = user.gloves.germ_level

	//Germs from the tool
	if(tool)
		our_germ_level += tool.germ_level
	//No tool, pretend the surgeon is the tool
	else
		our_germ_level *= 2

	//Germs from the dirtiness on the surgery room
	var/turf/open/floor/floor = get_turf(bodypart.owner)
	if(istype(floor))
		our_germ_level += floor.germ_level

	//Divide it by 3 to be reasonable
	our_germ_level = CEILING(our_germ_level/3, 1)

	//If the patient has antibiotics, kill germs by an amount equal to 10x the antibiotic force
	//e.g. nalixidic acid has 35 force, thus would decrease germs here by 350
	var/antibiotics = bodypart.owner.get_antibiotics()
	our_germ_level = max(0, our_germ_level - (antibiotics * 10))

	//This amount is not meaningful enough to cause an infection
	if(our_germ_level < INFECTION_LEVEL_ONE/2)
		return

	. = TRUE

	//If we still have germs, let's get that W

	//Injuries first
	for(var/datum/injury/injury as anything in bodypart.injuries)
		if((injury.required_status == BODYPART_ORGANIC) && (injury.germ_level < SURGERY_GERM_MAXIMUM))
			injury.adjust_germ_level(our_germ_level, maximum_germs = SURGERY_GERM_MAXIMUM)

	//Then, infect the organs on the bodypart
	for(var/obj/item/organ/organ as anything in bodypart.get_organs())
		if(organ.is_organic_organ() && !CHECK_BITFIELD(organ.organ_flags, ORGAN_NOINFECTION) && (organ.germ_level < SURGERY_GERM_MAXIMUM))
			organ.adjust_germ_level(our_germ_level, maximum_germs = SURGERY_GERM_MAXIMUM)

	//Then, infect the bodypart
	if(bodypart.is_organic_limb() && !CHECK_BITFIELD(bodypart.limb_flags, BODYPART_NOINFECTION) && (bodypart.germ_level < SURGERY_GERM_MAXIMUM))
		bodypart.adjust_germ_level(our_germ_level, maximum_germs = SURGERY_GERM_MAXIMUM)

/obj/item/proc/unspeculumize(obj/item/source, mob/living/affected_mob, obj/item/bodypart/limb)
	for(var/datum/component/embedded/embedded_source as anything in source.GetComponents(/datum/component/embedded))
		if(embedded_source.injury)
			embedded_source.injury.injury_flags &= ~INJURY_RETRACTED
	if(istype(affected_mob))
		playsound(source, 'modular_septic/sound/gore/stuck1.ogg', 60, 0)
		affected_mob.update_damage_overlays()
	source.UnregisterSignal(source, COMSIG_ITEM_UNEMBEDDED)


code:
/obj/item/organ
	name = "organ"
	icon = 'modular_septic/icons/obj/surgery.dmi'
	force = 0
	throwforce = 0
	w_class = WEIGHT_CLASS_NORMAL

	/// Germ level is treated as the infection level of an organ, we start at 0 and only increase when appropriate
	germ_level = 0

	/// Mob we are currently attached to
	var/mob/living/carbon/owner = null
	/// The first mob we got attached to
	var/datum/weakref/original_owner = null

	/// Organic or robotic
	var/status = ORGAN_ORGANIC

	/// Default body zone we occupy
	var/zone = BODY_ZONE_CHEST
	/// Body zone we are currently occupying
	var/current_zone = null
	/// Body zones we can be inserted on
	var/list/possible_zones = ALL_BODYPARTS

	/// Some organs have a side of the body they occupy - this should only be used for icon updates
	var/side = NO_SIDE
	/// Efficiency attached to each slot
	var/list/organ_efficiency
	/// Used if the organ doesn't use organ processes and a mob can only have one
	var/unique_slot

	/// General flags
	var/organ_flags = ORGAN_EDIBLE
	/// Does this organ not show up on the body scanner?
	var/scanner_hidden = FALSE
	/// If someone has written something stupid on us
	var/etching = ""

	/// The space we occupy inside a limb - unaffected by w_class for balance reasons
	var/organ_volume = 0
	/// How much blood an organ can store - Base is 5 * blood_req, so the organ can survive without blood for 10 seconds before taking damage (+ blood supply of arteries)
	var/max_blood_storage = 0
	/// How much blood is currently in the organ
	var/current_blood = 0
	/// How much blood (percent of BLOOD_VOLUME_NORMAL) an organ takes to funcion
	var/blood_req = 0
	/// If oxygen reqs are not satisfied, get debuffs and brain starts taking damage
	var/oxygen_req = 0
	/// Controls passive nutriment loss
	var/nutriment_req = 0
	/// Controls passive hydration loss
	var/hydration_req = 0

	/// Damage healed per second
	var/healing_factor = STANDARD_ORGAN_HEALING
	/// Minimum amount of germ_level we gain when rotting
	var/min_decay_factor = MIN_ORGAN_DECAY_INFECTION
	/// Maximum amount of germ_level we gain when rotting
	var/max_decay_factor = MAX_ORGAN_DECAY_INFECTION
	/// Total damage this organ has sustained
	var/damage = 0
	/// Maximum amount of damage we can suffer
	var/maxHealth = STANDARD_ORGAN_THRESHOLD
	/// How much pain this causes in relation to damage (pain_multiplier * damage)
	var/pain_multiplier = 0.75
	/// Modifier for when the parent limb gets damaged, and fucks up the organs inside
	var/internal_damage_modifier = 1
	/// Flat reduction of the damage when the limb gets damaged and fucks us up
	var/internal_damage_reduction = 0
	/// When severe organ damage (broken) occurs
	var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.8
	/// When medium organ damage occurs (only matters for bones at the moment)
	var/medium_threshold = STANDARD_ORGAN_THRESHOLD * 0.5
	/// When minor organ damage (bruising) occurs
	var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.2
	/// Cooldown for severe effects, used for synthetic organ emp effects.
	COOLDOWN_DECLARE(severe_cooldown)
	/// Time left to keep failing for
	var/failure_time = 0
	/// Last amount of damage we were at
	var/prev_damage = 0
	/// Just passed bruise threshold
	var/low_threshold_passed
	/// Just passed medium threshold
	var/medium_threshold_passed
	/// Just passed the broken treshold
	var/high_threshold_passed
	/// Organ is failing
	var/now_failing
	/// Organ has been fixed from failing
	var/now_fixed
	/// Organ has been fixed below broken
	var/high_threshold_cleared
	/// Organ has been fixed below medium
	var/medium_threshold_cleared
	/// Organ has been fixed below bruised
	var/low_threshold_cleared

	/// Used to handle rejection from incompatible owner
	var/rejection_stage = 0
	/// You can only really try to fix an organ via surgery once... or something
	var/operated = FALSE
	/// Prevents running constantly failing code
	var/failed = FALSE
	/// When you take a bite you cant jam it in for surgery anymore.
	var/functional = TRUE

	/// Used to handle EMP effects
	var/emp_vulnerability = 0

	/// Reagents the edible component gets
	var/list/food_reagents = list(/datum/reagent/consumable/nutriment = 5, \
							/datum/reagent/consumable/nutriment/protein = 5, \
							/datum/reagent/consumable/nutriment/organ_tissue = 5)
	/// The size of the reagent container
	var/reagent_vol = 20

	/// Types of items that can stitch this organ when severed
	var/list/attaching_items = list(/obj/item/stack/medical/suture)
	/// If this is set, this organ can be healed with item types in this list
	var/list/healing_items = list(/obj/item/stack/medical/suture)
	/// The above, but for tool behaviors
	var/list/healing_tools

	/// Should this get colored by mutantpart_info?
	var/mutantpart_colored = FALSE
	///	With what DNA block do we mutate in mutate_feature() ? For genetics
	var/dna_block
	/// This is for associating an organ with a mutant bodypart - Look at tails for examples
	var/mutantpart_key
	var/list/list/mutantpart_info

/obj/item/organ/Initialize()
	. = ..()
	START_PROCESSING(SSobj, src)
	current_zone = zone
	if(mutantpart_colored && mutantpart_key)
		color = mutantpart_info[MUTANT_INDEX_COLOR][1]
	if(organ_flags & ORGAN_EDIBLE)
		AddComponent(/datum/component/edible, \
			initial_reagents = food_reagents, \
			foodtypes = RAW|MEAT|GROSS, \
			volume = reagent_vol, \
			after_eat = CALLBACK(src, .proc/on_eat_from))
	update_appearance()

//Wtf?
/obj/item/organ/add_weapon_description()
	return

/obj/item/organ/proc/on_eat_from(eater, feeder)
	functional = FALSE //You can't use it anymore after eating it you spaztic
	applyOrganDamage(maxHealth/4)

/obj/item/organ/Destroy()
	if(owner)
		// The special flag is important, because otherwise mobs can die
		// while undergoing transformation into different mobs.
		Remove(owner, special = TRUE)
	return ..()

/obj/item/organ/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
	. = ..()
	if(status == ORGAN_ORGANIC)
		playsound(get_turf(src), 'sound/misc/splort.ogg', 50, TRUE, -1)

/*
 * Insert the organ into the select mob.
 *
 * receiver - the mob who will get our organ
 * special - "quick swapping" an organ out - when TRUE, the mob will be unaffected by not having that organ for the moment
 * drop_if_replaced - if there's an organ in the slot already, whether we drop it afterwards
 */
/obj/item/organ/proc/Insert(mob/living/carbon/receiver, special = FALSE, drop_if_replaced = TRUE, new_zone = null)
	. = FALSE
	if(!istype(receiver) || owner == receiver)
		return

	if(!isnull(new_zone))
		current_zone = new_zone
	else
		current_zone = zone

	var/obj/item/bodypart/parent_part = receiver.get_bodypart(current_zone)
	if(!parent_part && !special)
		current_zone = zone

	if(unique_slot)
		var/obj/item/organ/replaced = receiver.getorganslot(unique_slot)
		if(replaced)
			replaced.Remove(receiver, special = TRUE)
			if(drop_if_replaced)
				replaced.forceMove(get_turf(receiver))
			else
				qdel(replaced)
	SEND_SIGNAL(src, COMSIG_ORGAN_IMPLANTED, receiver)
	SEND_SIGNAL(receiver, COMSIG_CARBON_GAIN_ORGAN, src, special)

	owner = receiver
	receiver.internal_organs |= src
	for(var/slot in organ_efficiency)
		LAZYADD(receiver.internal_organs_slot[slot], src)
	moveToNullspace()
	RegisterSignal(owner, COMSIG_PARENT_EXAMINE, .proc/on_owner_examine)
	for(var/X in actions)
		var/datum/action/action = X
		action.Grant(receiver)
	STOP_PROCESSING(SSobj, src)
	handle_rejection()
	. = TRUE
	if(!(receiver.status_flags & BUILDING_ORGANS))
		receiver.update_organ_requirements()
		if(mutantpart_key && ishuman(receiver))
			receiver.dna.species.mutant_bodyparts[mutantpart_key] = mutantpart_info.Copy()
			receiver.update_body()
		if(organ_flags & ORGAN_LIMB_SUPPORTER)
			var/obj/item/bodypart/affected = owner.get_bodypart(current_zone)
			affected?.update_limb_efficiency()

/*
 * Remove the organ from the select mob.
 *
 * organ_owner - the mob who owns our organ, that we're removing the organ from.
 * special - "quick swapping" an organ out - when TRUE, the mob will be unaffected by not having that organ for the moment
 */
/obj/item/organ/proc/Remove(mob/living/carbon/organ_owner, special = FALSE)
	UnregisterSignal(owner, COMSIG_PARENT_EXAMINE)

	var/initial_zone = current_zone
	owner = null
	current_zone = zone
	if(organ_owner)
		organ_owner.internal_organs -= src
		for(var/slot in organ_efficiency)
			LAZYREMOVE(organ_owner.internal_organs_slot[slot], src)
			if(!length(organ_owner.internal_organs_slot[slot]))
				organ_owner.internal_organs_slot -= slot
		if(!special && CHECK_BITFIELD(organ_flags, ORGAN_VITAL) && !(organ_owner.status_flags & GODMODE))
			organ_owner.death()
	for(var/X in actions)
		var/datum/action/action = X
		action.Remove(organ_owner)
	SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner)
	SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special)
	START_PROCESSING(SSobj, src)
	organ_flags |= ORGAN_CUT_AWAY
	if(!(organ_owner.status_flags & BUILDING_ORGANS))
		organ_owner.update_organ_requirements()
		if(mutantpart_key && ishuman(organ_owner))
			if(organ_owner.dna.species.mutant_bodyparts[mutantpart_key])
				mutantpart_info = organ_owner.dna.species.mutant_bodyparts[mutantpart_key].Copy() //Update the info in case it was changed on the person
			if(mutantpart_colored)
				color = sanitize_hexcolor(mutantpart_info[MUTANT_INDEX_COLOR][1], 6, TRUE)
			organ_owner.dna.species.mutant_bodyparts -= mutantpart_key
			organ_owner.update_body()
		if(organ_flags & ORGAN_LIMB_SUPPORTER)
			var/obj/item/bodypart/affected = organ_owner.get_bodypart(initial_zone)
			affected?.update_limb_efficiency()

/obj/item/organ/proc/on_owner_examine(datum/source, mob/user, list/examine_list)
	return

/obj/item/organ/proc/on_find(mob/living/finder)
	return

/obj/item/organ/proc/switch_side(new_side = RIGHT_SIDE)
	side = new_side
	update_appearance()

/// when a limb is dropped, the internal organs are removed from the mob and put into the limb
/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/new_limb, mob/living/carbon/was_owner)
	if(owner)
		Remove(owner)
	forceMove(new_limb)

/// Adding/removing germs
/obj/item/organ/adjust_germ_level(add_germs, minimum_germs = 0, maximum_germs = MAXIMUM_GERM_LEVEL)
	. = ..()
	if(germ_level >= INFECTION_LEVEL_THREE && !CHECK_BITFIELD(organ_flags, ORGAN_DEAD))
		kill_organ()

/// Infection/rot checks
/obj/item/organ/proc/can_decay()
	check_cold()
	if(CHECK_BITFIELD(organ_flags, ORGAN_FROZEN|ORGAN_DEAD|ORGAN_SYNTHETIC|ORGAN_NOINFECTION))
		return FALSE
	else if(owner?.reagents?.has_reagent(/datum/reagent/toxin/formaldehyde, 0.5) || owner?.reagents?.has_reagent(/datum/reagent/cryostylane, 0.5))
		return FALSE
	return TRUE

/// runs decay when outside of a person
/obj/item/organ/process(delta_time, times_fired)
	on_death(delta_time, times_fired) //Kinda hate doing it like this, but I really don't want to call process directly.

/// runs decay when outside of a person
/obj/item/organ/proc/on_death(delta_time, times_fired)
	if(can_decay())
		decay(delta_time)
	else
		STOP_PROCESSING(SSobj, src)

/// proper decaying
/obj/item/organ/proc/decay(delta_time)
	check_cold()
	if(CHECK_BITFIELD(organ_flags, ORGAN_DEAD | ORGAN_FROZEN))
		return
	if(!owner)
		organ_flags |= ORGAN_CUT_AWAY
	adjust_germ_level(rand(min_decay_factor,max_decay_factor) * delta_time)

/// healing checks
/obj/item/organ/proc/can_heal(delta_time, times_fired)
	. = TRUE
	if(!owner)
		return FALSE
	if(healing_factor <= 0)
		return FALSE
	if((damage > maxHealth/5) && !owner.get_chem_effect(CE_ORGAN_REGEN))
		return FALSE
	if(is_dead())
		return FALSE
	if(current_blood <= 0)
		return FALSE
	if(owner.undergoing_cardiac_arrest())
		return FALSE

/// repair organ damage if the organ is not failing
/obj/item/organ/proc/on_life(delta_time, times_fired)
	SHOULD_CALL_PARENT(TRUE)
	if(!owner)
		return

	/// Handle germs before anything else!
	if(can_decay())
		if(rejection_stage)
			handle_rejection(delta_time, times_fired)
		handle_germ_effects(delta_time, times_fired)
		handle_antibiotics(delta_time, times_fired)
	else
		germ_level = 0

	/// Handle blood
	handle_blood(delta_time, times_fired)

	if(is_failing())
		handle_failing_organ(delta_time, times_fired)
		return

	// Synthetic organ has been emped, apply damage until it starts failing
	if(is_emped())
		applyOrganDamage(healing_factor * delta_time)
		return

	// Decrease failure time while healthy
	if(failure_time > 0)
		failure_time = max(0, failure_time - delta_time)

	// Damage decrements by a percent of maxhealth
	if(can_heal(delta_time, times_fired) && damage)
		handle_healing(delta_time, times_fired)

/obj/item/organ/proc/handle_blood(delta_time, times_fired)
	var/arterial_efficiency = get_slot_efficiency(ORGAN_SLOT_ARTERY)
	var/in_bleedout = owner.in_bleedout()
	if(arterial_efficiency && !is_failing())
		// Arteries get an extra flat 5 blood regen
		current_blood = min(current_blood + 5 * (0.5 * delta_time) * (arterial_efficiency/ORGAN_OPTIMAL_EFFICIENCY), max_blood_storage)
		return
	if(!blood_req)
		return
	if(!in_bleedout)
		current_blood = min(current_blood + (blood_req * (0.5 * delta_time)), max_blood_storage)
		return
	current_blood = max(current_blood - (blood_req * (0.5 * delta_time)), 0)
	// When all blood is lost, take blood from blood vessels
	if(!current_blood)
		var/obj/item/organ/artery
		var/obj/item/bodypart/parent = owner.get_bodypart(current_zone)
		for(var/thing in shuffle(parent?.getorganslotlist(ORGAN_SLOT_ARTERY)))
			var/obj/item/organ/candidate = thing
			if(candidate.current_blood && (candidate.get_slot_efficiency(ORGAN_SLOT_ARTERY) >= ORGAN_FAILING_EFFICIENCY))
				artery = candidate
				break
		if(artery?.current_blood)
			var/prev_blood = artery.current_blood
			artery.current_blood = max(artery.current_blood - (blood_req * 0.5 * delta_time), 0)
			current_blood = max(prev_blood - artery.current_blood, 0)
		if(current_blood <= 0)
			applyOrganDamage(2 * delta_time)

/obj/item/organ/proc/handle_healing(delta_time, times_fired)
	if(damage)
		applyOrganDamage(-healing_factor * delta_time, damage)
		//this doesn't seem very right at all...
		owner.adjust_nutrition(-nutriment_req * (0.5 * delta_time))
		owner.adjust_hydration(-hydration_req * (0.5 * delta_time))

/// Rejection caused by unmatching owner DNA
/obj/item/organ/proc/handle_rejection(delta_time, times_fired)
	if(CHECK_BITFIELD(organ_flags, ORGAN_SYNTHETIC))
		rejection_stage = 0
		return

	// Process unsuitable transplants. TODO: consider some kind of
	// immunosuppressant that changes transplant data to make it match.
	var/antibiotics = owner.get_antibiotics()
	if(antibiotics >= 50) //for now just having antibiotics will suppress it
		if(DT_PROB(antibiotics*0.2, delta_time))
			original_owner = WEAKREF(owner)
			rejection_stage = 0
		return

	var/mob/living/carbon/og_owner = original_owner?.resolve()
	if(og_owner?.dna?.blood_type)
		var/datum/dna/original_dna = og_owner.dna
		if(!rejection_stage)
			if(!(owner.dna.blood_type in get_safe_blood(original_dna.blood_type)))
				rejection_stage = REJECTION_LEVEL_1
		else
			//Rejection severity increases over time.
			rejection_stage += (0.5 * delta_time)
			//Only fire every ten rejection ticks.
			if(!(rejection_stage % 10))
				switch(rejection_stage)
					if(REJECTION_LEVEL_1 to REJECTION_LEVEL_2)
						adjust_germ_level(1 * (0.5 * delta_time))
					if(REJECTION_LEVEL_2 to REJECTION_LEVEL_3)
						adjust_germ_level(rand(1,2) * (0.5 * delta_time))
					if(REJECTION_LEVEL_3 to REJECTION_LEVEL_4)
						adjust_germ_level(rand(2,3) * (0.5 * delta_time))
					if(REJECTION_LEVEL_4 to INFINITY)
						adjust_germ_level(rand(3,5) * (0.5 * delta_time))
						owner.reagents.add_reagent(/datum/reagent/toxin, rand(1,2))
	else
		original_owner = WEAKREF(owner)
		rejection_stage = 0
		return

/// Malus caused by germs
/obj/item/organ/proc/handle_germ_effects(delta_time, times_fired)
	var/virus_immunity = owner?.virus_immunity()
	var/antibiotics = owner?.get_antibiotics()

	if(germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && DT_PROB(virus_immunity*0.15, delta_time))
		adjust_germ_level(-1 * (0.5 * delta_time))
		return

	if(germ_level >= INFECTION_LEVEL_ONE/2)
		//Aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes, when immunity is full.
		if(antibiotics < 5 && DT_PROB(round(germ_level/6 * owner.immunity_weakness() * 0.005), delta_time))
			if(virus_immunity > 0)
				adjust_germ_level(clamp(round(1/virus_immunity), 1, 10) * (0.5 * delta_time)) // Immunity starts at 100. This doubles infection rate at 50% immunity. Rounded to nearest whole.
			else // Will only trigger if immunity has hit zero. Once it does, 10x infection rate.
				adjust_germ_level(10 * (0.5 * delta_time))

	if(germ_level >= INFECTION_LEVEL_ONE && antibiotics < 20)
		var/fever_temperature = (BODYTEMP_HEAT_DAMAGE_LIMIT - BODYTEMP_NORMAL - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + BODYTEMP_NORMAL
		owner.adjust_bodytemperature(clamp((fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, 0, fever_temperature - owner.bodytemperature), use_insulation = FALSE)

	if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < 25)
		var/obj/item/bodypart/bodypart = owner.get_bodypart(current_zone)
		if(bodypart)
			//Spread germs
			if(antibiotics < 5 && bodypart.germ_level < germ_level && (bodypart.germ_level < INFECTION_LEVEL_ONE*2 || DT_PROB(owner.immunity_weakness() * 0.15, delta_time)))
				bodypart.adjust_germ_level(1 * (0.5 * delta_time))
		//Cause organ damage about once every ~30 seconds
		//The bodypart deals with dealing raw toxin damage, let's not stack onto the problem now
		if(DT_PROB(2, delta_time))
			applyOrganDamage(2)

	// Organ is just completely dead by this point
	if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 40)
		var/obj/item/bodypart/bodypart = owner.get_bodypart(current_zone)
		if(bodypart)
			// Spread germs really badly
			if(antibiotics < 10 && bodypart.germ_level < germ_level && (bodypart.germ_level < INFECTION_LEVEL_THREE))
				bodypart.adjust_germ_level(1 * (0.5 * delta_time))

/// Antibiotics combating germs and stuff
/obj/item/organ/proc/handle_antibiotics(delta_time, times_fired)
	if(!owner || (germ_level <= 0))
		return

	var/antibiotics = owner.get_antibiotics()
	if(antibiotics <= 0)
		return

	if((germ_level < INFECTION_LEVEL_ONE) && (antibiotics >= 20))
		set_germ_level(GERM_LEVEL_STERILE)
	else
		adjust_germ_level(-antibiotics * SANITIZATION_ANTIBIOTIC * (0.5 * delta_time))	//at germ_level == 500 and 50 antibiotic, this should cure the infection in 5 minutes
		if(owner?.body_position == LYING_DOWN)
			adjust_germ_level(-SANITIZATION_LYING * (0.5 * delta_time))

/// So we don't grant the organ's action to mobs who pick up the organ.
/obj/item/organ/item_action_slot_check(slot,mob/user)
	return

/// Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
/obj/item/organ/proc/applyOrganDamage(amount, maximum = maxHealth, silent = FALSE) //use for damaging effects
	if(!amount) //Micro-optimization.
		return
	if(maximum < damage)
		damage = maximum
	if(damage < 0 && owner?.get_chem_effect(CE_ORGAN_REGEN))
		damage *= 2
	prev_damage = damage
	damage = clamp(damage + amount, 0, maximum)
	var/mess = check_damage_thresholds(owner)
	if(!mess && (damage - prev_damage >= ORGAN_DAMAGE_NOTIFY_PLAYER))
		mess = span_userdanger("Something inside my [parse_zone(current_zone)] hurts!")
	if(owner)
		if(mess && !silent)
			to_chat(owner, mess)
		if(organ_flags & ORGAN_LIMB_SUPPORTER)
			var/obj/item/bodypart/affected = owner.get_bodypart(current_zone)
			affected?.update_limb_efficiency()

/// SETS an organ's damage to the amount "d", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
/obj/item/organ/proc/setOrganDamage(d, silent = FALSE) // use mostly for admin heals
	applyOrganDamage(d - damage)

/** check_damage_thresholds
 * input: holder (a mob, the owner of the organ we call the proc on)
 * output: returns a message should get displayed.
 * description: By checking our current damage against our previous damage, we can decide whether we've passed an organ threshold.
 *  If we have, send the corresponding threshold message to the owner, if such a message exists.
 */
/obj/item/organ/proc/check_damage_thresholds(mob/living/carbon/holder)
	if(damage == prev_damage)
		return
	var/delta = damage - prev_damage
	if(delta > 0)
		if(damage >= maxHealth && prev_damage < maxHealth)
			organ_flags |= ORGAN_FAILING
			if(!(organ_flags & ORGAN_INDESTRUCTIBLE))
				organ_flags |= ORGAN_DESTROYED
			return now_failing
		if(damage >= high_threshold && prev_damage < high_threshold)
			organ_flags |= ORGAN_FAILING
			return high_threshold_passed
		if(damage >= medium_threshold && prev_damage < medium_threshold)
			return medium_threshold_passed
		if(damage >= low_threshold && prev_damage < low_threshold)
			return low_threshold_passed
	else
		if(prev_damage >= low_threshold && damage < low_threshold)
			organ_flags &= ~ORGAN_FAILING
			return low_threshold_cleared
		if(prev_damage >= medium_threshold && damage < medium_threshold)
			organ_flags &= ~ORGAN_FAILING
			return medium_threshold_cleared
		if(prev_damage >= high_threshold && damage < high_threshold)
			organ_flags &= ~ORGAN_FAILING
			return high_threshold_cleared
		if(prev_damage >= maxHealth && damage < maxHealth)
			return now_fixed

/obj/item/organ/proc/can_feel_pain()
	. = FALSE
	// Robotic organs do not feel pain, simply for balancing reasons
	// Thus lowering the shock of IPCs and other synths is easier, as
	// they don't have many painkillers
	if(status == ORGAN_ROBOTIC)
		return FALSE
	if(pain_multiplier <= 0)
		return FALSE
	if(CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY | ORGAN_DEAD))
		return FALSE
	if(HAS_TRAIT(src, TRAIT_NOPAIN))
		return FALSE
	if(owner?.can_feel_pain())
		return TRUE

/obj/item/organ/proc/get_shock(painkiller_included = FALSE)
	if(!can_feel_pain())
		return 0
	// Failing organs always cause maxHealth pain if possible
	if(is_failing())
		return round(maxHealth * pain_multiplier, DAMAGE_PRECISION)
	var/constant_pain = damage
	if(painkiller_included)
		constant_pain -= (owner.get_chem_effect(CE_PAINKILLER)/4)
	return max(FLOOR(constant_pain * pain_multiplier, DAMAGE_PRECISION), 0)

///Get mutant part info from a dna datum
/obj/item/organ/proc/build_from_dna(datum/dna/dna_datum, associated_key)
	if(!dna_datum.species.mutant_bodyparts[associated_key])
		return
	mutantpart_key = associated_key
	mutantpart_info = dna_datum.species.mutant_bodyparts[associated_key].Copy()

// this only matters for kidneys and liver
/obj/item/organ/proc/add_toxins(amount)
	return 0

/obj/item/organ/proc/remove_toxins(amount)
	return 0

/obj/item/organ/proc/get_toxins()
	return 0

/obj/item/organ/proc/can_add_toxins()
	return FALSE

/obj/item/organ/proc/can_remove_toxins()
	return FALSE

// Checks to see if the organ is frozen from temperature and adds the ORGAN_FROZEN flag if so
/obj/item/organ/proc/check_cold()
	if(istype(loc, /obj/))//Freezer of some kind, I hope.
		if(is_type_in_typecache(loc, GLOB.freezing_objects))
			if(!(organ_flags & ORGAN_FROZEN))//Incase someone puts them in when cold, but they warm up inside of the thing. (i.e. they have the flag, the thing turns it off, this rights it.)
				organ_flags |= ORGAN_FROZEN
			return TRUE
		return (organ_flags & ORGAN_FROZEN) //Incase something else toggles it

	var/local_temp
	if(!owner)
		if(istype(loc, /turf))//Only concern is adding an organ to a freezer when the area around it is cold.
			var/turf/T = loc
			var/datum/gas_mixture/enviro = T.return_air()
			local_temp = enviro.temperature
		else if(ismob(loc))
			var/mob/M = loc
			if(is_type_in_typecache(M.loc, GLOB.freezing_objects))
				if(!(organ_flags & ORGAN_FROZEN))
					organ_flags |= ORGAN_FROZEN
				return TRUE
			var/turf/T = M.loc
			var/datum/gas_mixture/enviro = T.return_air()
			local_temp = enviro.temperature
	else
		// Don't interfere with bodies frozen by structures.
		if(is_type_in_typecache(owner.loc, GLOB.freezing_objects))
			if(!(organ_flags & ORGAN_FROZEN))
				organ_flags |= ORGAN_FROZEN
			return TRUE
		local_temp = owner.bodytemperature

	if(!local_temp) // Shouldn't happen but just in case
		return
	if(local_temp < 154)//I have a pretty shaky citation that states -120 allows indefinite cyrostorage
		organ_flags |= ORGAN_FROZEN
		return TRUE

	organ_flags &= ~ORGAN_FROZEN
	return FALSE

///Organs don't die instantly, and neither should you when you get fucked up
/obj/item/organ/proc/handle_failing_organ(delta_time, times_fired)
	if(!owner || owner.stat >= DEAD)
		return

	failure_time += delta_time
	organ_failure(delta_time)

/** organ_failure
 * generic proc for handling dying organs
 *
 * Arguments:
 * delta_time - seconds since last tick
 */
/obj/item/organ/proc/organ_failure(delta_time)
	return

/** get_availability
 * returns whether the species should innately have this organ.
 *
 * regenerate organs works with generic organs, so we need to get whether it can accept certain organs just by what this returns.
 * This is set to return true or false, depending on if a species has a specific organless trait. stomach for example checks if the species has NOSTOMACH and return based on that.
 * Arguments:
 * S - species, needed to return whether the species has an organ specific trait
 */
/obj/item/organ/proc/get_availability(datum/species/S)
	return TRUE

/// Called before organs are replaced in regenerate_organs with new ones
/obj/item/organ/proc/before_organ_replacement(obj/item/organ/replacement)
	return FALSE

/**
 * returns the efficiency for a specific organ slot
 *
 * Arguments:
 * slot - Slot we want to get the efficiency from
 */
/obj/item/organ/proc/get_slot_efficiency(slot)
	var/effective_efficiency = organ_efficiency[slot]
	if(isnull(effective_efficiency))
		return null
	if(slot != ORGAN_SLOT_ARTERY)
		if(is_failing())
			return 0
	else
		if(is_failing_without_bleedout())
			return 0
	effective_efficiency = max(0, CEILING(effective_efficiency - (organ_efficiency[slot] * (damage/maxHealth)), 1))
	return effective_efficiency

/obj/item/organ/proc/is_working()
	return (!CHECK_BITFIELD(organ_flags, ORGAN_FAILING|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_CUT_AWAY) && (damage < high_threshold) && (current_blood || !max_blood_storage) && functional)

/obj/item/organ/proc/is_working_without_bleedout()
	return (!CHECK_BITFIELD(organ_flags, ORGAN_FAILING|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_CUT_AWAY) && (damage < high_threshold) && functional)

/obj/item/organ/proc/is_failing()
	return (CHECK_BITFIELD(organ_flags, ORGAN_FAILING|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_CUT_AWAY) || (damage >= high_threshold) || (!current_blood && max_blood_storage && !LAZYACCESS(organ_efficiency, ORGAN_SLOT_ARTERY)) || !functional)

/obj/item/organ/proc/is_failing_without_bleedout()
	return (CHECK_BITFIELD(organ_flags, ORGAN_FAILING|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_CUT_AWAY) || (damage >= high_threshold) ||  !functional)

/obj/item/organ/proc/is_emped()
	return (CHECK_MULTIPLE_BITFIELDS(organ_flags, ORGAN_SYNTHETIC|ORGAN_SYNTHETIC_EMP))

/obj/item/organ/proc/is_bruised()
	return (damage >= low_threshold)

/obj/item/organ/proc/is_broken()
	return (CHECK_BITFIELD(organ_flags, ORGAN_FAILING) || (damage >= high_threshold))

/obj/item/organ/proc/is_destroyed()
	return (CHECK_BITFIELD(organ_flags, ORGAN_DESTROYED))

/obj/item/organ/proc/is_dead()
	return (CHECK_BITFIELD(organ_flags, ORGAN_DESTROYED|ORGAN_DEAD) || (germ_level >= INFECTION_LEVEL_THREE) || (damage >= maxHealth) || !functional)

/obj/item/organ/proc/is_necrotic()
	return (CHECK_BITFIELD(organ_flags, ORGAN_DEAD) || (germ_level >= INFECTION_LEVEL_THREE))

/obj/item/organ/proc/is_organic_organ()
	return ((status == ORGAN_ORGANIC) && !CHECK_BITFIELD(organ_flags, ORGAN_SYNTHETIC))

/obj/item/organ/proc/is_robotic_organ()
	return ((status == ORGAN_ROBOTIC) && CHECK_BITFIELD(organ_flags, ORGAN_SYNTHETIC))

/obj/item/organ/proc/bruise_organ()
	. = FALSE
	if(damage < low_threshold)
		setOrganDamage(low_threshold)
		return TRUE

/obj/item/organ/proc/break_organ()
	. = FALSE
	if(damage < high_threshold)
		setOrganDamage(high_threshold)
		return TRUE

/obj/item/organ/proc/kill_organ()
	. = FALSE
	if(damage < maxHealth && !CHECK_BITFIELD(organ_flags, ORGAN_DESTROYED))
		setOrganDamage(maxHealth)
		return TRUE

/obj/item/organ/proc/revive_organ()
	. = FALSE
	if(CHECK_BITFIELD(organ_flags, ORGAN_DESTROYED|ORGAN_FAILING|ORGAN_DEAD))
		setOrganDamage(0)
		organ_flags &= ~ORGAN_DESTROYED|ORGAN_FAILING|ORGAN_DEAD
		return TRUE

/obj/item/organ/proc/necrose_organ()
	. = FALSE
	if(!CHECK_BITFIELD(organ_flags, ORGAN_DEAD))
		set_germ_level(INFECTION_LEVEL_THREE)
		return TRUE

/obj/item/organ/proc/unnecrose_organ()
	. = FALSE
	if(CHECK_BITFIELD(organ_flags, ORGAN_DEAD))
		set_germ_level(GERM_LEVEL_STERILE)
		organ_flags &= ~ORGAN_DEAD
		return TRUE

/obj/item/organ/proc/cut_away_organ()
	. = FALSE
	if(!CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
		organ_flags |= ORGAN_CUT_AWAY
		return TRUE

/obj/item/organ/proc/sew_organ()
	. = FALSE
	if(CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
		organ_flags &= ~ORGAN_CUT_AWAY
		return TRUE


code:
/// Used by some medical tools
/obj/item/organ/proc/listen()
	return

/// Medical scans
/obj/item/organ/proc/get_scan_results(do_span = FALSE)
	. = list()
	if(status == ORGAN_ROBOTIC)
		. += do_span ? span_notice("Mechanical") : "Mechanical"

	if(CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
		. += do_span ? span_danger("Severed") : "Severed"

	if(rejection_stage)
		. += do_span ? span_danger("Genetic Rejection") : "Genetic Rejection"

	if(CHECK_BITFIELD(organ_flags, ORGAN_DEAD))
		. += do_span ? span_necrosis("Necrotic") : "Necrotic"
	else
		switch(germ_level)
			if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + ((INFECTION_LEVEL_TWO - INFECTION_LEVEL_ONE) / 3))
				. += do_span ? span_infection("Light Infection") : "Light Infection"
			if(INFECTION_LEVEL_ONE + ((INFECTION_LEVEL_TWO - INFECTION_LEVEL_ONE) / 3) to INFECTION_LEVEL_ONE + (2 * (INFECTION_LEVEL_TWO - INFECTION_LEVEL_ONE) / 3))
				. += do_span ? span_infection("Medium Infection+") : "Medium Infection+"
			if(INFECTION_LEVEL_ONE + (2 * (INFECTION_LEVEL_TWO - INFECTION_LEVEL_ONE) / 3) to INFECTION_LEVEL_TWO)
				. += do_span ? span_infection("Serious Infection") : "Serious Infection"
			if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + ((INFECTION_LEVEL_THREE - INFECTION_LEVEL_THREE) / 3))
				. += do_span ? span_infection("Acute Infection") : "Acute Infection"
			if(INFECTION_LEVEL_TWO + ((INFECTION_LEVEL_THREE - INFECTION_LEVEL_THREE) / 3) to INFECTION_LEVEL_TWO + (2 * (INFECTION_LEVEL_THREE - INFECTION_LEVEL_TWO) / 3))
				. += do_span ? span_infection("Acute Infection+") : "Acute Infection+"
			if(INFECTION_LEVEL_TWO + (2 * (INFECTION_LEVEL_THREE - INFECTION_LEVEL_TWO) / 3) to INFECTION_LEVEL_THREE)
				. += do_span ? span_infection("Acute Infection++") : "Acute Infection++"
			if(INFECTION_LEVEL_THREE to INFINITY)
				. += do_span ? span_necrosis("Septic") : "Septic"

/// Advanced examine stuff
/obj/item/organ/examine_more(mob/user)
	. = list(span_notice("I examine [src] closer, and note the following..."), "

")
	. |= surgical_examine(user)

/obj/item/organ/proc/surgical_examine(mob/user)
	. = list()
	var/failing = FALSE
	var/decayed = FALSE
	var/damaged = FALSE
	if(status == BODYPART_ROBOTIC)
		. += span_notice("[capitalize(src.name)] is seemingly of a robotic nature.")
	else
		. += span_notice("[capitalize(src.name)] is seemingly of an organic nature.")
	if(GetComponent(/datum/component/edible))
		. += span_notice("[capitalize(src.name)] is edible.")
	if(organ_flags & ORGAN_NOINFECTION)
		. += span_notice("[capitalize(src.name)] will not decay nor get infected.")
	if(organ_flags & ORGAN_UNREMOVABLE)
		. += span_notice("[capitalize(src.name)] cannot be removed via normal means.")
	if(organ_flags & ORGAN_VITAL)
		. += span_warning("[capitalize(src.name)] is a vital organ.")
	if(organ_flags & ORGAN_SYNTHETIC_EMP)
		. += span_danger("[capitalize(src.name)] has been EMPed!")
	else if(organ_flags & ORGAN_SYNTHETIC)
		. += span_warning("[capitalize(src.name)] is susceptible to electromagnetic pulses.")
	if(is_necrotic())
		decayed = TRUE
	if(is_dead())
		failing = TRUE
		. += span_warning("[capitalize(src.name)] is destroyed!")
	else if(is_failing())
		failing = TRUE
		. += span_warning("[capitalize(src.name)] is failing!")
	if(damage > low_threshold)
		if(!failing)
			damaged = TRUE
			if(status == ORGAN_ORGANIC)
				if(istype(src, /obj/item/organ/bone))
					. += span_warning("[capitalize(src.name)] has some cracks on the surface.")
				else
					. += span_warning("[capitalize(src.name)] is starting to look discolored.")
			else
				if(istype(src, /obj/item/organ/bone))
					. += span_warning("[capitalize(src.name)] is a bit bent.")
				else
					. += span_warning("[capitalize(src.name)] is leaking some oil.")
	if(!failing && !damaged && !decayed)
		. += span_notice("[capitalize(src.name)] seems to be decently healthy.")
	if(decayed)
		. += span_necrosis("[capitalize(src.name)] seems to be gangrenous!")
	else if(germ_level)
		switch(germ_level)
			if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_TWO)
				. += span_infection("[capitalize(src.name)] seems to be mildly infected.")
			if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE)
				. += span_infection("[capitalize(src.name)] seems to be festering.")
			if(INFECTION_LEVEL_THREE to INFINITY)
				. += span_necrosis("[capitalize(src.name)] seems to be necrotic!")
	if(owner)
		if(CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
			. += span_danger("[capitalize(src.name)] has been severed from [owner].")
		else
			. += span_notice("[capitalize(src.name)] is still attached to [owner].")
	if(etching)
		. += span_notice("[capitalize(src.name)] has \"[etching]\" inscribed on it.")
	if(side != NO_SIDE)
		var/side_result = "None"
		if((side & LEFT_SIDE) && (side & RIGHT_SIDE))
			side_result = "Both"
		else if(side & LEFT_SIDE)
			side_result = "Left"
		else if(side & RIGHT_SIDE)
			side_result = "Right"
		. += span_notice("Body side: [side_result]")
	if(GET_MOB_ATTRIBUTE_VALUE(user, SKILL_SURGERY) >= 8)
		. += span_info("Organ volume: [organ_volume]")
		var/requirement_string = "Requirements: "
		requirement_string += "[blood_req] "
		requirement_string += "[oxygen_req] "
		requirement_string += "[nutriment_req] "
		requirement_string += "[hydration_req] "
		requirement_string += ""
		. += requirement_string
	if(GET_MOB_ATTRIBUTE_VALUE(user, SKILL_SURGERY) >= 12)
		. += span_info("Efficiencies:")
		for(var/slot in organ_efficiency)
			. += "[capitalize_like_old_man(slot)]: [organ_efficiency[slot]]"
	if(!owner && GET_MOB_ATTRIBUTE_VALUE(user, SKILL_SURGERY) >= 8)
		. += span_info("This organ is normally inserted in:")
		. += span_info("[capitalize_like_old_man(parse_zone(zone))]")
		var/list/parsed_zones = possible_zones.Copy()
		for(var/thing in parsed_zones)
			parsed_zones -= thing
			parsed_zones += capitalize_like_old_man(parse_zone(thing))
		if(!length(parsed_zones))
			parsed_zones += "Nowhere"
		. += span_info("This organ can be inserted in:\n[jointext(parsed_zones, ", ")].")

/// Used by injuries
/obj/item/organ/proc/get_visible_state()
	if(is_destroyed())
		. = "destroyed "
	else if(is_broken())
		. = "broken "
	else if(is_bruised())
		. = "badly damaged "
	else if(damage >= 3)
		. = "damaged "
	if(CHECK_BITFIELD(organ_flags, ORGAN_DEAD))
		. = "gangrenous [.]"
	. = "[.][name]"


code:
/**
 * Get a random organ object from the mob matching the passed in typepath
 *
 * Arguments:
 * * typepath The typepath of the organ to get
 */
/mob/proc/getorgan(typepath)
	return

/**
 * Get a list of organ objects from the mob matching the passed in typepath
 *
 * Arguments:
 * * typepath The typepath of the organ to get
 */
/mob/proc/getorganlist(typepath)
	return

/**
 * Get organ objects by zone
 *
 * This will return a list of all the organs that are relevant to the zone that is passedin
 *
 * Arguments:
 * * zone [a BODY_ZONE_X define](https://github.com/tgstation/tgstation/blob/master/code/__DEFINES/combat.dm#L187-L200)
 */
/mob/proc/getorganszone(zone)
	return

/**
 * Returns a random organ out of all organs in specified slot
 *
 * Arguments:
 * * slot Slot to get the organ from
 */
/mob/proc/getorganslot(slot)
	return

/**
 * Returns a list of all organs in the specified slot, if there are any
 *
 * Arguments:
 * * slot Slot to get the list
 */
/mob/proc/getorganslotlist(slot)
	return

/**
 * Returns a list of all organs in the specified slot, in the specified zone, if there are any
 *
 * Arguments:
 * * slot Slot to get the list
 */
/mob/proc/getorganslotlistzone(slot, zone)
	return

/**
 * Returns an integer referring to the efficiency of a certain organ slot
 *
 * Arguments:
 * * slot Slot to get the efficiency from
 */
/mob/proc/getorganslotefficiency(slot)
	return

/**
 * Returns an integer referring to the efficiency of a certain organ slot within a specific body zone
 *
 * Arguments:
 * * slot Slot to get the efficiency from
 * * zone Body zone that the organ needs to be from
 */
/mob/proc/getorganslotefficiencyzone(slot)
	return

/**
 * Updates organ blood, oxygen and nutriment requirements
 */
/mob/proc/update_organ_requirements()
	return

/mob/living/carbon/getorgan(typepath)
	var/list/organs = list()
	for(var/thing in internal_organs)
		if(istype(thing, typepath))
			organs |= thing
	if(length(organs))
		return pick(organs)

/mob/living/carbon/getorganlist(typepath)
	var/list/organs = list()
	for(var/thing in internal_organs)
		if(istype(thing, typepath))
			organs |= thing
	return organs

/mob/living/carbon/getorganszone(zone)
	var/list/returnorg = list()
	for(var/X in internal_organs)
		var/obj/item/organ/O = X
		if(zone == O.current_zone)
			returnorg += O
	return returnorg

/mob/living/carbon/getorganslot(slot)
	if(length(internal_organs_slot[slot]))
		return pick(internal_organs_slot[slot])

/mob/living/carbon/getorganslotlist(slot)
	. = list()
	if(length(internal_organs_slot[slot]))
		. |= internal_organs_slot[slot]

/mob/living/carbon/getorganslotlistzone(slot, zone)
	. = list()
	if(length(internal_organs_slot[slot]))
		for(var/thing in internal_organs_slot[slot])
			var/obj/item/organ/organ = thing
			if(zone == organ.current_zone)
				. |= organ

/mob/living/carbon/getorganslotefficiency(slot)
	. = 0
	var/list/organs = internal_organs_slot[slot]
	for(var/thing in organs)
		var/obj/item/organ/organ = thing
		. += organ.get_slot_efficiency(slot)

/mob/living/carbon/getorganslotefficiencyzone(slot, zone)
	. = 0
	var/list/organs = internal_organs_slot[slot]
	for(var/thing in organs)
		var/obj/item/organ/organ = thing
		if(zone == organ.current_zone)
			. += organ.get_slot_efficiency(slot)

/mob/living/carbon/update_organ_requirements()
	if(status_flags & BUILDING_ORGANS)
		return
	total_blood_req = 0
	total_oxygen_req = 0
	total_nutriment_req = 0
	total_hydration_req = 0
	for(var/thing in internal_organs)
		var/obj/item/organ/organ = thing
		total_blood_req += (organ.blood_req/100 * BLOOD_VOLUME_NORMAL)
		total_oxygen_req += organ.oxygen_req
		total_nutriment_req += (organ.nutriment_req/1000)
		total_hydration_req += (organ.hydration_req/1000)

/**
 * Regenerates all standard organs of the body.
 */
/mob/living/proc/regenerate_organs()
	return FALSE

/mob/living/carbon/regenerate_organs()
	if(dna?.species)
		dna.species.regenerate_organs(src, replace_current = TRUE)
		return
	else
		var/list/lungs = getorganslotlist(ORGAN_SLOT_LUNGS)
		if(length(lungs) < 2)
			while(length(lungs) < 2)
				var/obj/item/organ/lungs/lung = new()
				lung.Insert(src)
		for(var/thing in lungs)
			var/obj/item/organ/lungs/lung = thing
			lung.setOrganDamage(0)

		var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
		if(!H)
			H = new()
			H.Insert(src)
		H.setOrganDamage(0)

		var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
		if(!T)
			T = new()
			T.Insert(src)
		T.setOrganDamage(0)

		var/list/ears = getorganslotlist(ORGAN_SLOT_EARS)
		if(LAZYLEN(ears) < 2)
			while(LAZYLEN(ears) < 2)
				var/obj/item/organ/ears/ear = new()
				ear.Insert(src)
		for(var/thing in ears)
			var/obj/item/organ/ears/ear = thing
			ear.setOrganDamage(0)

/**
 * Get a random organ object from the bodypart matching the passed in typepath
 *
 * Arguments:
 * * typepath The typepath of the organ to get
 */
/obj/item/bodypart/proc/getorgan(typepath)
	if(owner)
		for(var/thing in shuffle(owner.getorganszone(body_zone)))
			if(istype(thing, typepath))
				return thing
	else
		var/list/organs = list()
		for(var/thing in src)
			if(istype(thing, typepath))
				organs |= thing
		if(length(organs))
			return pick(organs)

/**
 * Get a list of organ objects from the bodypart matching the passed in typepath
 *
 * Arguments:
 * * typepath The typepath of the organ to get
 */
/obj/item/bodypart/proc/getorganlist(typepath)
	var/list/organs = list()
	if(owner)
		for(var/thing in owner.getorganszone(body_zone))
			if(istype(thing, typepath))
				organs |= thing
	else
		for(var/thing in src)
			if(istype(thing, typepath))
				organs |= thing
	return organs

/**
 * Returns a random organ out of all organs in specified slot inside of the bodypart
 *
 * Arguments:
 * * slot Slot to get the organ from
 */
/obj/item/bodypart/proc/getorganslot(slot)
	if(owner)
		for(var/thing in shuffle(owner.getorganslotlist(slot)))
			var/obj/item/organ/organ = thing
			if(organ.current_zone == body_zone)
				return organ
	else
		var/list/organs = list()
		for(var/obj/item/organ/organ in src)
			if(slot in organ.organ_efficiency)
				organs |= organ
		if(length(organs))
			return pick(shuffle(organs))

/**
 * Returns a list of all organs in the specified slot inside this limb, if there are any
 *
 * Arguments:
 * * slot Slot to get the list
 */
/obj/item/bodypart/proc/getorganslotlist(slot)
	var/list/organs = list()
	if(owner)
		for(var/thing in owner.getorganslotlist(slot))
			var/obj/item/organ/organ = thing
			if(organ.current_zone == body_zone)
				organs |= organ
	else
		for(var/obj/item/organ/organ in src)
			if(slot in organ.organ_efficiency)
				organs |= organ
	return organs

/**
 * Returns the organ efficiency in a specific limb
 * Arguments:
 * * slot Slot to get the efficiency from
 */
/obj/item/bodypart/proc/getorganslotefficiency(slot)
	if(owner)
		return owner.getorganslotefficiencyzone(slot, body_zone)
	else
		. = null
		for(var/obj/item/organ/organ in src)
			. += organ.get_slot_efficiency(slot)


code:
//This file mostly handles healing organs and other weird shit
/obj/item/organ/attackby(obj/item/I, mob/living/user, params)
	. = ..()
	return handle_organ_attack(I, user, params)

/obj/item/organ/proc/handle_organ_attack(obj/item/tool, mob/living/user, params)
	if(owner && DOING_INTERACTION_WITH_TARGET(user, owner))
		return TRUE
	else if(DOING_INTERACTION_WITH_TARGET(user, src))
		return TRUE
	if(owner && CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
		for(var/thing in attaching_items)
			if(istype(tool, thing))
				handle_attaching_item(tool, user, params)
				return TRUE
	for(var/thing in healing_items)
		if(istype(tool, thing))
			handle_healing_item(tool, user, params)
			return TRUE
	for(var/thing in healing_tools)
		if(tool.tool_behaviour == thing)
			handle_healing_item(tool, user, params)
			return TRUE
	if(owner && CHECK_BITFIELD(tool.get_sharpness(), SHARP_EDGED) && !CHECK_BITFIELD(organ_flags, ORGAN_CUT_AWAY))
		handle_cutting_away(tool, user, params)
		return TRUE

/obj/item/organ/proc/handle_attaching_item(obj/item/tool, mob/living/user, params)
	var/obj/item/stack/stack = tool
	user.visible_message(span_notice("[user] starts attaching \the [src] on \the [owner]..."), \
					span_notice("I start attaching \the [src] on \the [owner]..."), \
					vision_distance = COMBAT_MESSAGE_RANGE)
	owner.custom_pain("OH GOD! There is something ripping me from inside!", 30, FALSE, owner.get_bodypart(current_zone))
	if(!do_mob(user, owner, 3 SECONDS))
		to_chat(user, span_warning("I must stand still!"))
		return
	if(istype(stack) && !stack.use(2))
		to_chat(user, span_warning("I don't have enough to attach \the [src]!"))
		return
	user.visible_message(span_notice("[user] attaches \the [src] safely on \the [owner]."), \
						span_notice("I attach \the [src] safely on \the [owner]."))
	organ_flags &= ~ORGAN_CUT_AWAY

/obj/item/organ/proc/handle_healing_item(obj/item/tool, mob/living/user, params)
	var/obj/item/stack/stack = tool
	if(organ_flags & (ORGAN_DESTROYED|ORGAN_DEAD))
		to_chat(user, span_warning("\The [src] is damaged beyond the point of no return."))
		return
	if(!damage)
		to_chat(user, span_notice("\The [src] is in pristine quality already."))
		return
	user.visible_message(span_notice("[user] starts healing \the [src]..."), \
					span_notice("I start healing \the [src]..."), \
					vision_distance = COMBAT_MESSAGE_RANGE)
	if(owner)
		owner.custom_pain("OH GOD! There are needles inside my [src]!", 30, FALSE, owner.get_bodypart(current_zone))
		if(!do_mob(user, owner, 5 SECONDS))
			to_chat(user, span_warning("I must stand still!"))
			return
	else
		if(!do_after(user, 5 SECONDS, src))
			to_chat(user, span_warning("I must stand still!"))
			return
	if(istype(stack))
		if(!stack.use(2))
			to_chat(user, span_warning("I don't have enough to heal \the [src]!"))
			return
	user.visible_message(span_notice("[user] healing \the [src]."), \
						span_notice("I heal \the [src]."))
	applyOrganDamage(-min(maxHealth/2, 50))

/obj/item/organ/proc/handle_cutting_away(obj/item/tool, mob/living/user, params)
	user.visible_message(span_notice("[user] starts severing \the [src] from \the [owner]..."), \
					span_notice("I start severing \the [src] from \the [owner]..."), \
					vision_distance = COMBAT_MESSAGE_RANGE)
	owner.custom_pain("OH GOD! My [src] is being STABBED!", 30, FALSE, owner.get_bodypart(current_zone))
	if(!do_mob(user, owner, 6 SECONDS))
		to_chat(user, span_warning("I must stand still!"))
		return TRUE
	user.visible_message(span_notice("[user] severs \the [src] away."), \
					span_notice("I sever \the [src] away."), \
					vision_distance = COMBAT_MESSAGE_RANGE)
	organ_flags |= ORGAN_CUT_AWAY
	return TRUE


code:
/datum/organ_process
	/// The slot we process
	var/slot = ""
	/// The mob types we process on
	var/list/mob_types = list(/mob/living/carbon)
	/// Need this to process dead mobs
	var/processes_dead = FALSE
	/// Equal or above this threshold means the process is functioning optimally
	var/optimal_threshold = ORGAN_OPTIMAL_EFFICIENCY
	/// Below this efficiency threshold, we consider the process bruised
	var/bruised_threshold = ORGAN_BRUISED_EFFICIENCY
	/// Below  this efficiency threshold, we consider the process failing
	var/failing_threshold = ORGAN_FAILING_EFFICIENCY
	/// Equal or below  this efficiency threshold, we consider the process destroyed
	var/destroyed_threshold = ORGAN_DESTROYED_EFFICIENCY

/// Checks if owner even makes use of this organ process
/datum/organ_process/proc/needs_process(mob/living/carbon/owner)
	SHOULD_CALL_PARENT(TRUE)
	if(owner.stat >= DEAD && !processes_dead)
		return FALSE
	if(!is_type_in_list(owner, mob_types))
		return FALSE
	return TRUE

/// Handles the processing, if we passed the proper checks
/datum/organ_process/proc/handle_process(mob/living/carbon/owner, delta_time = SSMOBS_DT, times_fired)
	return TRUE


code:
GLOBAL_LIST_INIT_TYPED(organ_processes_datums, /datum/organ_process, init_subtypes(/datum/organ_process))
GLOBAL_LIST_INIT_TYPED(organ_processes_by_slot, /datum/organ_process, world.setup_organ_processes_by_slot())

/world/proc/setup_organ_processes_by_slot()
	. = list()
	for(var/thing in GLOB.organ_processes_datums)
		var/datum/organ_process/organ_process = thing
		.[organ_process.slot] = organ_process


code:
/datum/organ_process/bladder
	slot = ORGAN_SLOT_BLADDER
	mob_types = list(/mob/living/carbon/human)

/datum/organ_process/bladder/needs_process(mob/living/carbon/owner)
	return (..() && !(NOBLADDER in owner.dna.species.species_traits))

/datum/organ_process/bladder/handle_process(mob/living/carbon/owner, delta_time, times_fired)
	var/list/bladders = owner.getorganslotlist(ORGAN_SLOT_BLADDER)
	var/needpee_event
	var/collective_piss_amount = 0
	for(var/obj/item/organ/bladder/bladder as anything in bladders)
		collective_piss_amount += (bladder.reagents.get_reagent_amount(/datum/reagent/consumable/piss) - bladder.food_reagents[/datum/reagent/consumable/piss])
	switch(collective_piss_amount)
		if(30 to 60)
			needpee_event = /datum/mood_event/needpiss
			if(DT_PROB(5, delta_time))
				to_chat(owner, span_warning(pick("I need to go to the bathroom.", "I need to pee.", "I need to take a leak.")))
		if(60 to INFINITY)
			needpee_event = /datum/mood_event/reallyneedpiss
			if(DT_PROB(10, delta_time))
				to_chat(owner, span_warning(pick("I <b>really</b> need to piss!", "My bladder is BLEEDING!", "I'm gonna piss myself!")))
	if(needpee_event)
		SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "need_pee", needpee_event)
	else
		SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "need_pee")
	return TRUE


code:
/datum/organ_process/brain
	slot = ORGAN_SLOT_BRAIN

/datum/organ_process/brain/handle_process(mob/living/carbon/owner, delta_time, times_fired)
	// this is crazy dumb code but it makes sense if you think enough about it
	var/effective_blood_oxygenation = GET_EFFECTIVE_BLOOD_VOL(owner.get_blood_oxygenation(), owner.total_blood_req)
	var/damprob = 0
	var/obj/item/organ/brain/brain = owner.getorganslot(ORGAN_SLOT_BRAIN)
	//Wtf?
	if(!brain)
		return
	var/is_stable = owner.get_chem_effect(CE_STABLE)
	// this handles general lack of blood oxygenation, but the brain itself also handles some stuff
	switch(effective_blood_oxygenation)
		if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
			if(DT_PROB(2.5, delta_time))
				to_chat(src, span_warning("I feel [pick("dizzy","woozy","faint")]."))
			owner.adjustOxyLoss(round(0.005 * (BLOOD_VOLUME_NORMAL - effective_blood_oxygenation) * delta_time, 1))
			damprob = is_stable? 10 : 30
			if((brain.current_blood <= 0) && !brain.past_damage_threshold(2) && DT_PROB(damprob, delta_time))
				brain.applyOrganDamage(BRAIN_DAMAGE_LOW_OXYGENATION)
		if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
			owner.blur_eyes(4)
			if(DT_PROB(5, delta_time))
				owner.Unconscious(rand(1,3) SECONDS)
				to_chat(owner, span_userdanger("I feel very [pick("dizzy","woozy","faint")]..."))
			owner.adjustOxyLoss(FLOOR(0.01 * (BLOOD_VOLUME_NORMAL - effective_blood_oxygenation) * delta_time, 1))
			damprob = is_stable ? 15 : 50
			if((brain.current_blood <= 0) && !brain.past_damage_threshold(4) && DT_PROB(damprob, delta_time))
				brain.applyOrganDamage(BRAIN_DAMAGE_LOW_OXYGENATION)
		if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
			owner.blur_eyes(6)
			if(DT_PROB(10, delta_time))
				owner.Unconscious(rand(3,5) SECONDS)
				to_chat(owner, span_userdanger("I feel extremely [pick("dizzy","woozy","faint")]..."))
			owner.adjustOxyLoss(2.5 * delta_time)
			damprob = is_stable ? 40 : 75
			if((brain.current_blood <= 0) && !brain.past_damage_threshold(6) && DT_PROB(damprob, delta_time))
				brain.applyOrganDamage(BRAIN_DAMAGE_LOWER_OXYGENATION)
		// Also see heart.dm, being below this point puts you into cardiac arrest no matter what
		if(-INFINITY to BLOOD_VOLUME_SURVIVE)
			owner.blur_eyes(6)
			if((brain.current_blood <= 0) && DT_PROB(7.5, delta_time))
				to_chat(owner, span_userdanger("I feel [pick("heavy", "dehydrated", "empty")] and [pick("faint", "weak", "lightheaded", "dizzy")]!"))
			owner.adjustOxyLoss(5 * delta_time)
			owner.Unconscious(rand(6,12) SECONDS)
			damprob = is_stable ? 65 : 100
			if((brain.current_blood <= 0) && DT_PROB(damprob, delta_time))
				brain.applyOrganDamage(BRAIN_DAMAGE_LOWEST_OXYGENATION)
	owner.handle_brain_damage()
	return TRUE


code:
/datum/organ_process/ears
	slot = ORGAN_SLOT_EARS
	mob_types = list(/mob/living/carbon/human)
	var/static/sound/ringing = sound('sound/weapons/flash_ring.ogg', FALSE, 0, CHANNEL_EAR_RING, 75)

/datum/organ_process/ears/handle_process(mob/living/carbon/owner, delta_time, times_fired)
	var/ear_efficiency = owner.getorganslotefficiency(ORGAN_SLOT_EARS)
	if(ear_efficiency < failing_threshold)
		ADD_TRAIT(owner, TRAIT_DEAF, EAR_DAMAGE)
	else
		REMOVE_TRAIT(owner, TRAIT_DEAF, EAR_DAMAGE)
	if((ear_efficiency < bruised_threshold) && DT_PROB((optimal_threshold - ear_efficiency)/bruised_threshold, delta_time))
		var/obj/item/organ/ears/ear = owner.getorganslot(ORGAN_SLOT_EARS)
		ear?.adjustEarDamage(0, 4)
		SEND_SOUND(owner, ringing)
	return TRUE