<commit_before>/obj/item/mecha_parts/mecha_equipment/tool/sleeper
	name = "Mounted Sleeper"
	desc = "Mounted Sleeper. (Can be attached to: Medical Exosuits)"
	icon = 'icons/obj/Cryogenic2.dmi'
	icon_state = "sleeper_0"
	origin_tech = "programming=2;biotech=3"
	energy_drain = 20
	range = MELEE
	construction_cost = list("metal"=5000,"glass"=10000)
	reliability = 1000
	equip_cooldown = 20
	var/mob/living/carbon/occupant = null
	var/datum/global_iterator/pr_mech_sleeper
	var/inject_amount = 10
	salvageable = 0

	can_attach(obj/mecha/medical/M)
		if(..())
			if(istype(M))
				return 1
		return 0

	New()
		..()
		pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0)
		pr_mech_sleeper.set_delay(equip_cooldown)
		return

	allow_drop()
		return 0

	destroy()
		for(var/atom/movable/AM in src)
			AM.forceMove(get_turf(src))
		return ..()

	Exit(atom/movable/O)
		return 0

	action(var/mob/living/carbon/target)
		if(!action_checks(target))
			return
		if(!istype(target))
			return
		if(target.buckled)
			occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled].")
			return
		if(occupant)
			occupant_message("The sleeper is already occupied")
			return
		for(var/mob/living/carbon/slime/M in range(1,target))
			if(M.Victim == target)
				occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.")
				return
		occupant_message("You start putting [target] into [src].")
		chassis.visible_message("[chassis] starts putting [target] into the [src].")
		var/C = chassis.loc
		var/T = target.loc
		if(do_after_cooldown(target))
			if(chassis.loc!=C || target.loc!=T)
				return
			if(occupant)
				occupant_message("<font color=\"red\"><B>The sleeper is already occupied!</B></font>")
				return
			target.forceMove(src)
			occupant = target
			target.reset_view(src)
			/*
			if(target.client)
				target.client.perspective = EYE_PERSPECTIVE
				target.client.eye = chassis
			*/
			set_ready_state(0)
			pr_mech_sleeper.start()
			occupant_message("<font color='blue'>[target] successfully loaded into [src]. Life support functions engaged.</font>")
			chassis.visible_message("[chassis] loads [target] into [src].")
			log_message("[target] loaded. Life support functions engaged.")
		return

	proc/go_out()
		if(!occupant)
			return
		occupant.forceMove(get_turf(src))
		occupant_message("[occupant] ejected. Life support functions disabled.")
		log_message("[occupant] ejected. Life support functions disabled.")
		occupant.reset_view()
		/*
		if(occupant.client)
			occupant.client.eye = occupant.client.mob
			occupant.client.perspective = MOB_PERSPECTIVE
		*/
		occupant = null
		pr_mech_sleeper.stop()
		set_ready_state(1)
		return

	detach()
		if(occupant)
			occupant_message("Unable to detach [src] - equipment occupied.")
			return
		pr_mech_sleeper.stop()
		return ..()

	get_equip_info()
		var/output = ..()
		if(output)
			var/temp = ""
			if(occupant)
				temp = "<br />\[Occupant: [occupant] (Health: [occupant.health]%)\]<br /><a href='?src=\ref[src];view_stats=1'>View stats</a>|<a href='?src=\ref[src];eject=1'>Eject</a>"
			return "[output] [temp]"
		return

	Topic(href,href_list)
		..()
		var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
		if(filter.get("eject"))
			go_out()
		if(filter.get("view_stats"))
			chassis.occupant << browse(get_occupant_stats(),"window=msleeper")
			onclose(chassis.occupant, "msleeper")
			return
		if(filter.get("inject"))
			inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source"))
		return

	proc/get_occupant_stats()
		if(!occupant)
			return
		return {"<html>
					<head>
					<title>[occupant] statistics</title>
					<script language='javascript' type='text/javascript'>
					[js_byjax]
					</script>
					<style>
					h3 {margin-bottom:2px;font-size:14px;}
					#lossinfo, #reagents, #injectwith {padding-left:15px;}
					</style>
					</head>
					<body>
					<h3>Health statistics</h3>
					<div id="lossinfo">
					[get_occupant_dam()]
					</div>
					<h3>Reagents in bloodstream</h3>
					<div id="reagents">
					[get_occupant_reagents()]
					</div>
					<div id="injectwith">
					[get_available_reagents()]
					</div>
					</body>
					</html>"}

	proc/get_occupant_dam()
		var/t1
		switch(occupant.stat)
			if(0)
				t1 = "Conscious"
			if(1)
				t1 = "Unconscious"
			if(2)
				t1 = "*dead*"
			else
				t1 = "Unknown"
		return {"<font color="[occupant.health > 50 ? "blue" : "red"]"><b>Health:</b> [occupant.health]% ([t1])</font><br />
					<font color="[occupant.bodytemperature > 50 ? "blue" : "red"]"><b>Core Temperature:</b> [src.occupant.bodytemperature-T0C]&deg;C ([src.occupant.bodytemperature*1.8-459.67]&deg;F)</font><br />
					<font color="[occupant.getBruteLoss() < 60 ? "blue" : "red"]"><b>Brute Damage:</b> [occupant.getBruteLoss()]%</font><br />
					<font color="[occupant.getOxyLoss() < 60 ? "blue" : "red"]"><b>Respiratory Damage:</b> [occupant.getOxyLoss()]%</font><br />
					<font color="[occupant.getToxLoss() < 60 ? "blue" : "red"]"><b>Toxin Content:</b> [occupant.getToxLoss()]%</font><br />
					<font color="[occupant.getFireLoss() < 60 ? "blue" : "red"]"><b>Burn Severity:</b> [occupant.getFireLoss()]%</font><br />
					"}

	proc/get_occupant_reagents()
		if(occupant.reagents)
			for(var/datum/reagent/R in occupant.reagents.reagent_list)
				if(R.volume > 0)
					. += "[R]: [round(R.volume,0.01)]<br />"
		return . || "None"

	proc/get_available_reagents()
		var/output
		var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun) in chassis
		if(SG && SG.reagents && islist(SG.reagents.reagent_list))
			for(var/datum/reagent/R in SG.reagents.reagent_list)
				if(R.volume > 0)
					output += "<a href=\"?src=\ref[src];inject=\ref[R];source=\ref[SG]\">Inject [R.name]</a><br />"
		return output


	proc/inject_reagent(var/datum/reagent/R,var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG)
		if(!R || !occupant || !SG || !(SG in chassis.equipment))
			return 0
		var/to_inject = min(R.volume, inject_amount)
		if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
			SG.reagents.trans_id_to(occupant,R.id,to_inject)
			occupant_message("[occupant] injected with [to_inject] units of [R.name].")
			log_message("[occupant] injected with [to_inject] units of [R.name].")
			update_equip_info()
		return

	update_equip_info()
		if(..())
			send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam())<commit_msg>Runtime fix for mech sleepers feedback messages at injecting the victim with the last units of a reagent.<commit_after>/obj/item/mecha_parts/mecha_equipment/tool/sleeper
	name = "Mounted Sleeper"
	desc = "Mounted Sleeper. (Can be attached to: Medical Exosuits)"
	icon = 'icons/obj/Cryogenic2.dmi'
	icon_state = "sleeper_0"
	origin_tech = "programming=2;biotech=3"
	energy_drain = 20
	range = MELEE
	construction_cost = list("metal"=5000,"glass"=10000)
	reliability = 1000
	equip_cooldown = 20
	var/mob/living/carbon/occupant = null
	var/datum/global_iterator/pr_mech_sleeper
	var/inject_amount = 10
	salvageable = 0

	can_attach(obj/mecha/medical/M)
		if(..())
			if(istype(M))
				return 1
		return 0

	New()
		..()
		pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0)
		pr_mech_sleeper.set_delay(equip_cooldown)
		return

	allow_drop()
		return 0

	destroy()
		for(var/atom/movable/AM in src)
			AM.forceMove(get_turf(src))
		return ..()

	Exit(atom/movable/O)
		return 0

	action(var/mob/living/carbon/target)
		if(!action_checks(target))
			return
		if(!istype(target))
			return
		if(target.buckled)
			occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled].")
			return
		if(occupant)
			occupant_message("The sleeper is already occupied")
			return
		for(var/mob/living/carbon/slime/M in range(1,target))
			if(M.Victim == target)
				occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.")
				return
		occupant_message("You start putting [target] into [src].")
		chassis.visible_message("[chassis] starts putting [target] into the [src].")
		var/C = chassis.loc
		var/T = target.loc
		if(do_after_cooldown(target))
			if(chassis.loc!=C || target.loc!=T)
				return
			if(occupant)
				occupant_message("<font color=\"red\"><B>The sleeper is already occupied!</B></font>")
				return
			target.forceMove(src)
			occupant = target
			target.reset_view(src)
			/*
			if(target.client)
				target.client.perspective = EYE_PERSPECTIVE
				target.client.eye = chassis
			*/
			set_ready_state(0)
			pr_mech_sleeper.start()
			occupant_message("<font color='blue'>[target] successfully loaded into [src]. Life support functions engaged.</font>")
			chassis.visible_message("[chassis] loads [target] into [src].")
			log_message("[target] loaded. Life support functions engaged.")
		return

	proc/go_out()
		if(!occupant)
			return
		occupant.forceMove(get_turf(src))
		occupant_message("[occupant] ejected. Life support functions disabled.")
		log_message("[occupant] ejected. Life support functions disabled.")
		occupant.reset_view()
		/*
		if(occupant.client)
			occupant.client.eye = occupant.client.mob
			occupant.client.perspective = MOB_PERSPECTIVE
		*/
		occupant = null
		pr_mech_sleeper.stop()
		set_ready_state(1)
		return

	detach()
		if(occupant)
			occupant_message("Unable to detach [src] - equipment occupied.")
			return
		pr_mech_sleeper.stop()
		return ..()

	get_equip_info()
		var/output = ..()
		if(output)
			var/temp = ""
			if(occupant)
				temp = "<br />\[Occupant: [occupant] (Health: [occupant.health]%)\]<br /><a href='?src=\ref[src];view_stats=1'>View stats</a>|<a href='?src=\ref[src];eject=1'>Eject</a>"
			return "[output] [temp]"
		return

	Topic(href,href_list)
		..()
		var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
		if(filter.get("eject"))
			go_out()
		if(filter.get("view_stats"))
			chassis.occupant << browse(get_occupant_stats(),"window=msleeper")
			onclose(chassis.occupant, "msleeper")
			return
		if(filter.get("inject"))
			inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source"))
		return

	proc/get_occupant_stats()
		if(!occupant)
			return
		return {"<html>
					<head>
					<title>[occupant] statistics</title>
					<script language='javascript' type='text/javascript'>
					[js_byjax]
					</script>
					<style>
					h3 {margin-bottom:2px;font-size:14px;}
					#lossinfo, #reagents, #injectwith {padding-left:15px;}
					</style>
					</head>
					<body>
					<h3>Health statistics</h3>
					<div id="lossinfo">
					[get_occupant_dam()]
					</div>
					<h3>Reagents in bloodstream</h3>
					<div id="reagents">
					[get_occupant_reagents()]
					</div>
					<div id="injectwith">
					[get_available_reagents()]
					</div>
					</body>
					</html>"}

	proc/get_occupant_dam()
		var/t1
		switch(occupant.stat)
			if(0)
				t1 = "Conscious"
			if(1)
				t1 = "Unconscious"
			if(2)
				t1 = "*dead*"
			else
				t1 = "Unknown"
		return {"<font color="[occupant.health > 50 ? "blue" : "red"]"><b>Health:</b> [occupant.health]% ([t1])</font><br />
					<font color="[occupant.bodytemperature > 50 ? "blue" : "red"]"><b>Core Temperature:</b> [src.occupant.bodytemperature-T0C]&deg;C ([src.occupant.bodytemperature*1.8-459.67]&deg;F)</font><br />
					<font color="[occupant.getBruteLoss() < 60 ? "blue" : "red"]"><b>Brute Damage:</b> [occupant.getBruteLoss()]%</font><br />
					<font color="[occupant.getOxyLoss() < 60 ? "blue" : "red"]"><b>Respiratory Damage:</b> [occupant.getOxyLoss()]%</font><br />
					<font color="[occupant.getToxLoss() < 60 ? "blue" : "red"]"><b>Toxin Content:</b> [occupant.getToxLoss()]%</font><br />
					<font color="[occupant.getFireLoss() < 60 ? "blue" : "red"]"><b>Burn Severity:</b> [occupant.getFireLoss()]%</font><br />
					"}

	proc/get_occupant_reagents()
		if(occupant.reagents)
			for(var/datum/reagent/R in occupant.reagents.reagent_list)
				if(R.volume > 0)
					. += "[R]: [round(R.volume,0.01)]<br />"
		return . || "None"

	proc/get_available_reagents()
		var/output
		var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun) in chassis
		if(SG && SG.reagents && islist(SG.reagents.reagent_list))
			for(var/datum/reagent/R in SG.reagents.reagent_list)
				if(R.volume > 0)
					output += "<a href=\"?src=\ref[src];inject=\ref[R];source=\ref[SG]\">Inject [R.name]</a><br />"
		return output


	proc/inject_reagent(var/datum/reagent/R,var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG)
		if(!R || !occupant || !SG || !(SG in chassis.equipment))
			return 0
		var/to_inject = min(R.volume, inject_amount)
		if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
			occupant_message("Injecting [occupant] with [to_inject] units of [R.name].")
			log_message("Injecting [occupant] with [to_inject] units of [R.name].")
			SG.reagents.trans_id_to(occupant,R.id,to_inject)
			update_equip_info()
		return

	update_equip_info()
		if(..())
			send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam())
{'fraction_non_alphanumeric': 0.1655395250976856, 'fraction_numerical': 0.012022843402464683, 'mean_word_length': 4.109021113243762, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 147, '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': '3863516', 'n_tokens_mistral': 5900, 'n_tokens_neox': 4977, 'n_words': 840}