<commit_before>
/obj/item/bodypart/proc/can_dismember(obj/item/I)
	if(dismemberable)
		. = (get_damage() >= (max_damage - I.armour_penetration/2))

//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
	if(!owner)
		return 0
	var/mob/living/carbon/C = owner
	if(!dismemberable)
		return 0
	if(C.status_flags & GODMODE)
		return 0
	if(ishuman(C))
		var/mob/living/carbon/human/H = C
		if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
			return 0

	var/obj/item/bodypart/affecting = C.get_bodypart("chest")
	affecting.receive_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage
	C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
	C.emote("scream")
	drop_limb()

	if(dam_type == BURN)
		burn()
		return 1
	add_mob_blood(C)
	var/turf/location = C.loc
	if(istype(location))
		C.add_splatter_floor(location)
	var/direction = pick(GLOB.cardinals)
	var/t_range = rand(2,max(throw_range/2, 2))
	var/turf/target_turf = get_turf(src)
	for(var/i in 1 to t_range-1)
		var/turf/new_turf = get_step(target_turf, direction)
		if(!new_turf)
			break
		target_turf = new_turf
		if(new_turf.density)
			break
	throw_at(target_turf, throw_range, throw_speed)
	return 1


/obj/item/bodypart/chest/dismember()
	if(!owner)
		return 0
	var/mob/living/carbon/C = owner
	if(!dismemberable)
		return 0
	if(ishuman(C))
		var/mob/living/carbon/human/H = C
		if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
			return 0

	var/organ_spilled = 0
	var/turf/T = get_turf(C)
	C.add_splatter_floor(T)
	playsound(get_turf(C), 'sound/misc/splort.ogg', 80, 1)
	for(var/X in C.internal_organs)
		var/obj/item/organ/O = X
		var/org_zone = check_zone(O.zone)
		if(org_zone != "chest")
			continue
		O.Remove(C)
		O.forceMove(T)
		organ_spilled = 1
	if(cavity_item)
		cavity_item.forceMove(T)
		cavity_item = null
		organ_spilled = 1

	if(organ_spilled)
		C.visible_message("<span class='danger'><B>[C]'s internal organs spill out onto the floor!</B></span>")
	return 1



//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special)
	if(!owner)
		return
	var/turf/T = get_turf(owner)
	var/mob/living/carbon/C = owner
	update_limb(1)
	C.bodyparts -= src

	if(held_index)
		C.dropItemToGround(owner.get_item_for_held_index(held_index), 1)
		C.hand_bodyparts[held_index] = null

	owner = null

	for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it.
		var/datum/surgery/S = X
		if(S.operated_bodypart == src)
			C.surgeries -= S
			qdel(S)
			break

	for(var/obj/item/I in embedded_objects)
		embedded_objects -= I
		I.loc = src
	if(!C.has_embedded_objects())
		C.clear_alert("embeddedobject")

	if(!special)
		if(C.dna)
			for(var/X in C.dna.mutations) //some mutations require having specific limbs to be kept.
				var/datum/mutation/human/MT = X
				if(MT.limb_req && MT.limb_req == body_zone)
					MT.force_lose(C)

		for(var/X in C.internal_organs) //internal organs inside the dismembered limb are dropped.
			var/obj/item/organ/O = X
			var/org_zone = check_zone(O.zone)
			if(org_zone != body_zone)
				continue
			O.transfer_to_limb(src, C)

	update_icon_dropped()
	forceMove(T)
	C.update_health_hud() //update the healthdoll
	C.update_body()
	C.update_hair()
	C.update_canmove()
	if(is_pseudopart)
		drop_organs(C)	//Psuedoparts shouldn't have organs, but just in case
		qdel(src)


//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/LB, mob/living/carbon/C)
	Remove(C)
	loc = LB

/obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)<commit_msg>Fixes a common runtime on prefs screen<commit_after>
/obj/item/bodypart/proc/can_dismember(obj/item/I)
	if(dismemberable)
		. = (get_damage() >= (max_damage - I.armour_penetration/2))

//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
	if(!owner)
		return 0
	var/mob/living/carbon/C = owner
	if(!dismemberable)
		return 0
	if(C.status_flags & GODMODE)
		return 0
	if(ishuman(C))
		var/mob/living/carbon/human/H = C
		if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
			return 0

	var/obj/item/bodypart/affecting = C.get_bodypart("chest")
	affecting.receive_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage
	C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
	C.emote("scream")
	drop_limb()

	if(dam_type == BURN)
		burn()
		return 1
	add_mob_blood(C)
	var/turf/location = C.loc
	if(istype(location))
		C.add_splatter_floor(location)
	var/direction = pick(GLOB.cardinals)
	var/t_range = rand(2,max(throw_range/2, 2))
	var/turf/target_turf = get_turf(src)
	for(var/i in 1 to t_range-1)
		var/turf/new_turf = get_step(target_turf, direction)
		if(!new_turf)
			break
		target_turf = new_turf
		if(new_turf.density)
			break
	throw_at(target_turf, throw_range, throw_speed)
	return 1


/obj/item/bodypart/chest/dismember()
	if(!owner)
		return 0
	var/mob/living/carbon/C = owner
	if(!dismemberable)
		return 0
	if(ishuman(C))
		var/mob/living/carbon/human/H = C
		if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
			return 0

	var/organ_spilled = 0
	var/turf/T = get_turf(C)
	C.add_splatter_floor(T)
	playsound(get_turf(C), 'sound/misc/splort.ogg', 80, 1)
	for(var/X in C.internal_organs)
		var/obj/item/organ/O = X
		var/org_zone = check_zone(O.zone)
		if(org_zone != "chest")
			continue
		O.Remove(C)
		O.forceMove(T)
		organ_spilled = 1
	if(cavity_item)
		cavity_item.forceMove(T)
		cavity_item = null
		organ_spilled = 1

	if(organ_spilled)
		C.visible_message("<span class='danger'><B>[C]'s internal organs spill out onto the floor!</B></span>")
	return 1



//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special)
	if(!owner)
		return
	var/turf/T = get_turf(owner)
	var/mob/living/carbon/C = owner
	update_limb(1)
	C.bodyparts -= src

	if(held_index)
		C.dropItemToGround(owner.get_item_for_held_index(held_index), 1)
		C.hand_bodyparts[held_index] = null

	owner = null

	for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it.
		var/datum/surgery/S = X
		if(S.operated_bodypart == src)
			C.surgeries -= S
			qdel(S)
			break

	for(var/obj/item/I in embedded_objects)
		embedded_objects -= I
		I.loc = src
	if(!C.has_embedded_objects())
		C.clear_alert("embeddedobject")

	if(!special)
		if(C.dna)
			for(var/X in C.dna.mutations) //some mutations require having specific limbs to be kept.
				var/datum/mutation/human/MT = X
				if(MT.limb_req && MT.limb_req == body_zone)
					MT.force_lose(C)

		for(var/X in C.internal_organs) //internal organs inside the dismembered limb are dropped.
			var/obj/item/organ/O = X
			var/org_zone = check_zone(O.zone)
			if(org_zone != body_zone)
				continue
			O.transfer_to_limb(src, C)

	update_icon_dropped()
	C.update_health_hud() //update the healthdoll
	C.update_body()
	C.update_hair()
	C.update_canmove()

	if(!T)	// T = null happens when a "dummy human" used for rendering icons on prefs screen gets its limbs replaced.
		qdel(src)
		return

	if(is_pseudopart)
		drop_organs(C)	//Psuedoparts shouldn't have organs, but just in case
		qdel(src)
		return

	forceMove(T)



//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/LB, mob/living/carbon/C)
	Remove(C)
	loc = LB

/obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)
{'fraction_non_alphanumeric': 0.12952261306532664, 'fraction_numerical': 0.008291457286432161, 'mean_word_length': 4.035420619860847, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2486670', 'n_tokens_mistral': 3582, 'n_tokens_neox': 3171, 'n_words': 659}