code:
/*
CONTAINS:
T-RAY
DETECTIVE SCANNER
HEALTH ANALYZER
GAS ANALYZER
MASS SPECTROMETER

*/
/obj/item/device/t_scanner
	name = "\improper T-ray scanner"
	desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
	icon_state = "t-ray0"
	var/on = 0
	slot_flags = SLOT_BELT
	w_class = 2
	item_state = "electronic"
	materials = list(MAT_METAL=150)
	origin_tech = "magnets=1;engineering=1"

/obj/item/device/t_scanner/attack_self(mob/user)

	on = !on
	icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"

	if(on)
		SSobj.processing |= src

/obj/item/device/t_scanner/proc/flick_sonar(obj/pipe)
	var/image/I = image('icons/effects/effects.dmi', pipe, "blip", pipe.layer+1)
	I.alpha = 128
	var/list/nearby = list()
	for(var/mob/M in viewers(pipe))
		if(M.client)
			nearby |= M.client
	flick_overlay(I,nearby,8)

/obj/item/device/t_scanner/process()
	if(!on)
		SSobj.processing.Remove(src)
		return null
	scan()

/obj/item/device/t_scanner/proc/scan()

	for(var/turf/T in range(2, src.loc) )
		for(var/obj/O in T.contents)

			if(O.level != 1)
				continue

			var/mob/living/L = locate() in O

			if(O.invisibility == 101)
				O.invisibility = 0
				if(L)
					flick_sonar(O)
				spawn(10)
					if(O && O.loc)
						var/turf/U = O.loc
						if(U.intact)
							O.invisibility = 101
			else
				if(L)
					flick_sonar(O)

/obj/item/device/healthanalyzer
	name = "health analyzer"
	icon_state = "health"
	item_state = "analyzer"
	desc = "A hand-held body scanner able to distinguish vital signs of the subject."
	flags = CONDUCT
	slot_flags = SLOT_BELT
	throwforce = 3
	w_class = 1
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=200)
	origin_tech = "magnets=1;biotech=1"
	var/mode = 1
	var/scanchems = 0

/obj/item/device/healthanalyzer/attack_self(mob/user)
	if(!scanchems)
		user << "You switch the health analyzer to scan chemical contents."
		scanchems = 1
	else
		user << "You switch the health analyzer to check physical health."
		scanchems = 0
	return
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)

	// Clumsiness/brain damage check
	if ((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50))
		user << "You stupidly try to analyze the floor's vitals!"
		user.visible_message("[user] has analyzed the floor's vitals!")
		user << "Analyzing results for The floor:\n\tOverall status: Healthy"
		user << "Key: Suffocation/Toxin/Burn/Brute"
		user << "\tDamage specifics: 0-0-0-0"
		user << "Body temperature: ???"
		return

	user.visible_message("[user] has analyzed [M]'s vitals.")

	if(!scanchems)
		healthscan(user, M, mode)
	else
		chemscan(user, M)

	src.add_fingerprint(user)
	return

// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
	if(user.stat || user.eye_blind)
		return
	//Damage specifics
	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 > 1 ? "Deceased" : "[round(M.health/M.maxHealth,0.01)*100] % healthy")

	if(M.status_flags & FAKEDEATH)
		mob_status = "Deceased"
		oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss

	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(H.heart_attack && H.stat != DEAD)
			user << "Subject suffering from heart attack: Apply defibrillator immediately!"
	user << "Analyzing results for [M]:\n\tOverall status: [mob_status]"

	// Damage descriptions
	if(brute_loss > 10)
		user << "\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected."
	if(fire_loss > 10)
		user << "\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected."
	if(oxy_loss > 10)
		user << "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected."
	if(tox_loss > 10)
		user << "\t[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected."
	if(M.getStaminaLoss())
		user << "\tSubject appears to be suffering from fatigue."
	if (M.getCloneLoss())
		user << "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage."
	if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
		user << "\tBloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals."
	if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/internal/brain))
		user << "\tSubject brain function is non-existant."
	else if (M.getBrainLoss() >= 60)
		user << "\tSevere brain damage detected. Subject likely to have mental retardation."
	else if (M.getBrainLoss() >= 10)
		user << "\tBrain damage detected. Subject may have had a concussion."

	// Organ damage report
	if(istype(M, /mob/living/carbon/human) && mode == 1)
		var/mob/living/carbon/human/H = M
		var/list/damaged = H.get_damaged_organs(1,1)
		if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0)
			user << "\tDamage: Brute-Burn-Toxin-Suffocation\n\t\tSpecifics: [brute_loss]-[fire_loss]-[tox_loss]-[oxy_loss]"
			for(var/obj/item/organ/limb/org in damaged)
				user << "\t\t[capitalize(org.getDisplayName())]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]"

	// Species and body temperature
	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		user << "Species: [H.dna.species.name]"
	user << "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)"

	// Time of death
	if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
		user << "Time of Death: [M.tod]"

	for(var/datum/disease/D in M.viruses)
		if(!(D.visibility_flags & HIDDEN_SCANNER))
			user << "Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]"

	// Blood Level
	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(H.vessel)
			if(H.blood_max)
				user << "Subject is bleeding!"
			var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
			var/blood_percent =  round((blood_volume / 560),0.01)
			var/blood_type = H.dna.blood_type
			blood_percent *= 100
			if(blood_volume <= 500 && blood_volume > 336)
				user << "LOW blood level [blood_percent] %, [blood_volume] cl, type: [blood_type]"
			else if(blood_volume <= 336)
				user << "CRITICAL blood level CRITICAL [blood_percent] %, [blood_volume] cl, type: [blood_type]"
			else
				user << "Blood level [blood_percent] %, [blood_volume] cl, type: [blood_type]"

		var/implant_detect
		for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs)
			if(CI.status == ORGAN_ROBOTIC)
				implant_detect += "[H.name] is modified with a [CI.name].
"
		if(implant_detect)
			user << "Detected cybernetic modifications:"
			user << "[implant_detect]"

/proc/chemscan(mob/living/user, mob/living/M)
	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(H.reagents)
			if(H.reagents.reagent_list.len)
				user << "Subject contains the following reagents:"
				for(var/datum/reagent/R in H.reagents.reagent_list)
					user << "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]"
			else
				user << "Subject contains no reagents."
			if(H.reagents.addiction_list.len)
				user << "Subject is addicted to the following reagents:"
				for(var/datum/reagent/R in H.reagents.addiction_list)
					user << "[R.name]"
			else
				user << "Subject is not addicted to any reagents."

/obj/item/device/healthanalyzer/verb/toggle_mode()
	set name = "Switch Verbosity"
	set category = "Object"

	if(usr.stat || !usr.canmove || usr.restrained())
		return

	mode = !mode
	switch (mode)
		if(1)
			usr << "The scanner now shows specific limb damage."
		if(0)
			usr << "The scanner no longer shows limb damage."

/obj/item/device/analyzer
	desc = "A hand-held environmental scanner which reports current gas levels."
	name = "analyzer"
	icon_state = "atmos"
	item_state = "analyzer"
	w_class = 2
	flags = CONDUCT
	slot_flags = SLOT_BELT
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=30, MAT_GLASS=20)
	origin_tech = "magnets=1;engineering=1"

/obj/item/device/analyzer/attack_self(mob/user)

	add_fingerprint(user)

	if (user.stat || user.eye_blind)
		return

	var/turf/location = user.loc
	if(!istype(location))
		return

	var/datum/gas_mixture/environment = location.return_air()

	var/pressure = environment.return_pressure()
	var/total_moles = environment.total_moles()

	user << "Results:"
	if(abs(pressure - ONE_ATMOSPHERE) < 10)
		user << "Pressure: [round(pressure,0.1)] kPa"
	else
		user << "Pressure: [round(pressure,0.1)] kPa"
	if(total_moles)
		var/list/env_gases = environment.gases

		environment.assert_gases(arglist(hardcoded_gases))
		var/o2_concentration = env_gases["o2"][MOLES]/total_moles
		var/n2_concentration = env_gases["n2"][MOLES]/total_moles
		var/co2_concentration = env_gases["co2"][MOLES]/total_moles
		var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles
		environment.garbage_collect()

		if(abs(n2_concentration - N2STANDARD) < 20)
			user << "Nitrogen: [round(n2_concentration*100, 0.01)] %"
		else
			user << "Nitrogen: [round(n2_concentration*100, 0.01)] %"

		if(abs(o2_concentration - O2STANDARD) < 2)
			user << "Oxygen: [round(o2_concentration*100, 0.01)] %"
		else
			user << "Oxygen: [round(o2_concentration*100, 0.01)] %"

		if(co2_concentration > 0.01)
			user << "CO2: [round(co2_concentration*100, 0.01)] %"
		else
			user << "CO2: [round(co2_concentration*100, 0.01)] %"

		if(plasma_concentration > 0.005)
			user << "Plasma: [round(plasma_concentration*100, 0.01)] %"
		else
			user << "Plasma: [round(plasma_concentration*100, 0.01)] %"

		for(var/id in env_gases)
			if(id in hardcoded_gases)
				continue
			var/gas_concentration = env_gases[id][MOLES]/total_moles
			user << "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %"
		user << "Temperature: [round(environment.temperature-T0C)] °C"

/obj/item/device/mass_spectrometer
	desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
	name = "mass-spectrometer"
	icon_state = "spectrometer"
	item_state = "analyzer"
	w_class = 2
	flags = CONDUCT | OPENCONTAINER
	slot_flags = SLOT_BELT
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=30, MAT_GLASS=20)
	origin_tech = "magnets=2;biotech=2"
	var/details = 0
	var/recent_fail = 0

/obj/item/device/mass_spectrometer/New()
	..()
	create_reagents(5)

/obj/item/device/mass_spectrometer/on_reagent_change()
	if(reagents.total_volume)
		icon_state = initial(icon_state) + "_s"
	else
		icon_state = initial(icon_state)

/obj/item/device/mass_spectrometer/attack_self(mob/user)
	if (user.stat || user.eye_blind)
		return
	if (crit_fail)
		user << "This device has critically failed and is no longer functional!"
		return
	if (!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		return
	if(reagents.total_volume)
		var/list/blood_traces = list()
		for(var/datum/reagent/R in reagents.reagent_list)
			if(R.id != "blood")
				reagents.clear_reagents()
				user << "The sample was contaminated! Please insert another sample."
				return
			else
				blood_traces = params2list(R.data["trace_chem"])
				break
		var/dat = "Trace Chemicals Found:"
		if(!blood_traces.len)
			dat += "
None"
		else
			for(var/R in blood_traces)
				if(prob(reliability))
					dat += "
[chemical_reagents_list[R]]"

					if(details)
						dat += " ([blood_traces[R]] units)"

					recent_fail = 0
				else
					if(recent_fail)
						crit_fail = 1
						reagents.clear_reagents()
						return
					else
						recent_fail = 1
		dat += ""
		user << dat
		reagents.clear_reagents()

/obj/item/device/mass_spectrometer/adv
	name = "advanced mass-spectrometer"
	icon_state = "adv_spectrometer"
	details = 1
	origin_tech = "magnets=4;biotech=2"

/obj/item/device/slime_scanner
	name = "slime scanner"
	desc = "A device that analyzes a slime's internal composition and measures its stats."
	icon_state = "adv_spectrometer"
	item_state = "analyzer"
	origin_tech = "biotech=1"
	w_class = 2
	flags = CONDUCT
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=30, MAT_GLASS=20)

/obj/item/device/slime_scanner/attack(mob/living/M, mob/living/user)
	if(user.stat || user.eye_blind)
		return
	if (!isslime(M))
		user << "This device can only scan slimes!"
		return
	var/mob/living/simple_animal/slime/T = M
	user << "Slime scan results:"
	user << "[T.colour] [T.is_adult ? "adult" : "baby"] slime"
	user << "Nutrition: [T.nutrition]/[T.get_max_nutrition()]"
	if (T.nutrition < T.get_starve_nutrition())
		user << "Warning: slime is starving!"
	else if (T.nutrition < T.get_hunger_nutrition())
		user << "Warning: slime is hungry"
	user << "Electric change strength: [T.powerlevel]"
	user << "Health: [round(T.health/T.maxHealth,0.01)*100]"
	if (T.slime_mutation[4] == T.colour)
		user << "This slime does not evolve any further."
	else
		if (T.slime_mutation[3] == T.slime_mutation[4])
			if (T.slime_mutation[2] == T.slime_mutation[1])
				user << "Possible mutation: [T.slime_mutation[3]]"
				user << "Genetic destability: [T.mutation_chance/2] % chance of mutation on splitting"
			else
				user << "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)"
				user << "Genetic destability: [T.mutation_chance] % chance of mutation on splitting"
		else
			user << "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]"
			user << "Genetic destability: [T.mutation_chance] % chance of mutation on splitting"
	if (T.cores > 1)
		user << "Anomalious slime core amount detected"
	user << "Growth progress: [T.amount_grown]/[SLIME_EVOLUTION_THRESHOLD]"


code:
/obj/item/device/sensor_device
	name = "handheld crew monitor" //Thanks to Gun Hog for the name!
	desc = "A miniature machine that tracks suit sensors across the station."
	icon = 'icons/obj/device.dmi'
	icon_state = "scanner"
	w_class = 2
	slot_flags = SLOT_BELT
	origin_tech = "programming=3;materials=3;magnets=3"

/obj/item/device/sensor_device/attack_self(mob/user)
	crewmonitor.show(user) //Proc already exists, just had to call it

license: mit


code:
/obj/item/device/taperecorder
	name = "universal recorder"
	desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
	icon_state = "taperecorder_empty"
	item_state = "analyzer"
	w_class = 2
	flags = HEAR
	slot_flags = SLOT_BELT
	languages = ALL //this is a translator, after all.
	materials = list(MAT_METAL=60, MAT_GLASS=30)
	force = 2
	throwforce = 0
	var/recording = 0
	var/playing = 0
	var/playsleepseconds = 0
	var/obj/item/device/tape/mytape
	var/open_panel = 0
	var/canprint = 1

/obj/item/device/taperecorder/New()
	mytape = new /obj/item/device/tape/random(src)
	update_icon()

/obj/item/device/taperecorder/examine(mob/user)
	..()
	user << "The wire panel is [open_panel ? "opened" : "closed"]."

/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
	if(!mytape && istype(I, /obj/item/device/tape))
		if(!user.unEquip(I))
			return
		I.loc = src
		mytape = I
		user << "You insert [I] into [src]."
		update_icon()

/obj/item/device/taperecorder/proc/eject(mob/user)
	if(mytape)
		user << "You remove [mytape] from [src]."
		stop()
		user.put_in_hands(mytape)
		mytape = null
		update_icon()

/obj/item/device/taperecorder/fire_act()
	mytape.ruin() //Fires destroy the tape
	return()

/obj/item/device/taperecorder/attack_hand(mob/user)
	if(loc == user)
		if(mytape)
			if(user.l_hand != src && user.r_hand != src)
				..()
				return
			eject(user)
			return
	..()

/obj/item/device/taperecorder/proc/can_use(mob/user)
	if(user && ismob(user))
		if(!user.incapacitated())
			return 1
	return 0

/obj/item/device/taperecorder/verb/ejectverb()
	set name = "Eject Tape"
	set category = "Object"

	if(!can_use(usr))
		return
	if(!mytape)
		return

	eject(usr)

/obj/item/device/taperecorder/update_icon()
	if(!mytape)
		icon_state = "taperecorder_empty"
	else if(recording)
		icon_state = "taperecorder_recording"
	else if(playing)
		icon_state = "taperecorder_playing"
	else
		icon_state = "taperecorder_idle"

/obj/item/device/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
	if(mytape && recording)
		mytape.timestamp += mytape.used_capacity
		mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [message]"

/obj/item/device/taperecorder/verb/record()
	set name = "Start Recording"
	set category = "Object"

	if(!can_use(usr))
		return
	if(!mytape || mytape.ruined)
		return
	if(recording)
		return
	if(playing)
		return

	if(mytape.used_capacity < mytape.max_capacity)
		usr << "Recording started."
		recording = 1
		update_icon()
		mytape.timestamp += mytape.used_capacity
		mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
		var/used = mytape.used_capacity	//to stop runtimes when you eject the tape
		var/max = mytape.max_capacity
		for(used, used < max)
			if(recording == 0)
				break
			mytape.used_capacity++
			used++
			sleep(10)
		recording = 0
		update_icon()
	else
		usr << "The tape is full."

/obj/item/device/taperecorder/verb/stop()
	set name = "Stop"
	set category = "Object"

	if(!can_use(usr))
		return

	if(recording)
		recording = 0
		mytape.timestamp += mytape.used_capacity
		mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
		usr << "Recording stopped."
		return
	else if(playing)
		playing = 0
		var/turf/T = get_turf(src)
		T.visible_message("Tape Recorder: Playback stopped.")
	update_icon()

/obj/item/device/taperecorder/verb/play()
	set name = "Play Tape"
	set category = "Object"

	if(!can_use(usr))
		return
	if(!mytape || mytape.ruined)
		return
	if(recording)
		return
	if(playing)
		return

	playing = 1
	update_icon()
	usr << "Playing started."
	var/used = mytape.used_capacity	//to stop runtimes when you eject the tape
	var/max = mytape.max_capacity
	for(var/i = 1, used < max, sleep(10 * playsleepseconds))
		if(!mytape)
			break
		if(playing == 0)
			break
		if(mytape.storedinfo.len < i)
			break
		say(mytape.storedinfo[i])
		if(mytape.storedinfo.len  14)
			sleep(10)
			say("Skipping [playsleepseconds] seconds of silence")
			playsleepseconds = 1
		i++

	playing = 0
	update_icon()

/obj/item/device/taperecorder/attack_self(mob/user)
	if(!mytape || mytape.ruined)
		return
	if(recording)
		stop()
	else
		record()

/obj/item/device/taperecorder/verb/print_transcript()
	set name = "Print Transcript"
	set category = "Object"

	if(!can_use(usr))
		return
	if(!mytape)
		return
	if(!canprint)
		usr << "The recorder can't print that fast!"
		return
	if(recording || playing)
		return

	usr << "Transcript printed."
	var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
	var/t1 = "Transcript:

"
	for(var/i = 1, mytape.storedinfo.len >= i, i++)
		t1 += "[mytape.storedinfo[i]]
"
	P.info = t1
	P.name = "paper- 'Transcript'"
	usr.put_in_hands(P)
	canprint = 0
	sleep(300)
	canprint = 1

//empty tape recorders
/obj/item/device/taperecorder/empty/New()
	return

/obj/item/device/tape
	name = "tape"
	desc = "A magnetic tape that can hold up to ten minutes of content."
	icon_state = "tape_white"
	item_state = "analyzer"
	w_class = 1
	materials = list(MAT_METAL=20, MAT_GLASS=5)
	force = 1
	throwforce = 0
	var/max_capacity = 600
	var/used_capacity = 0
	var/list/storedinfo = list()
	var/list/timestamp = list()
	var/ruined = 0

/obj/item/device/tape/fire_act()
	ruin()

/obj/item/device/tape/attack_self(mob/user)
	if(!ruined)
		user << "You pull out all the tape!"
		ruin()

/obj/item/device/tape/proc/ruin()
	overlays += "ribbonoverlay"
	ruined = 1

/obj/item/device/tape/proc/fix()
	overlays -= "ribbonoverlay"
	ruined = 0

/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
	if(ruined && istype(I, /obj/item/weapon/screwdriver))
		user << "You start winding the tape back in..."
		if(do_after(user, 120/I.toolspeed, target = src))
			user << "You wound the tape back in."
			fix()

//Random colour tapes
/obj/item/device/tape/random/New()
	icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"


code:
/*

Miscellaneous traitor devices

BATTERER

RADIOACTIVE MICROLASER

*/

/*

The Batterer, like a flashbang but 50% chance to knock people over. Can be either very
effective or pretty fucking useless.

*/

/obj/item/device/batterer
	name = "mind batterer"
	desc = "A strange device with twin antennas."
	icon_state = "batterer"
	throwforce = 5
	w_class = 1
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	item_state = "electronic"
	origin_tech = "magnets=3;combat=3;syndicate=3"

	var/times_used = 0 //Number of times it's been used.
	var/max_uses = 2

/obj/item/device/batterer/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
	if(!user) 	return
	if(times_used >= max_uses)
		user << "The mind batterer has been burnt out!"
		return

	add_logs(user, null, "knocked down people in the area", src)

	for(var/mob/living/carbon/human/M in urange(10, user, 1))
		if(prob(50))

			M.Weaken(rand(10,20))
			if(prob(25))
				M.Stun(rand(5,10))
			M << "You feel a tremendous, paralyzing wave flood your mind."

		else
			M << "You feel a sudden, electric jolt travel through your head."

	playsound(src.loc, 'sound/misc/interference.ogg', 50, 1)
	user << "You trigger [src]."
	times_used += 1
	if(times_used >= max_uses)
		icon_state = "battererburnt"

/*
		The radioactive microlaser, a device disguised as a health analyzer used to irradiate people.

		The strength of the radiation is determined by the 'intensity' setting, while the delay between
	the scan and the irradiation kicking in is determined by the wavelength.

		Each scan will cause the microlaser to have a brief cooldown period. Higher intensity will increase
	the cooldown, while higher wavelength will decrease it.

		Wavelength is also slightly increased by the intensity as well.
*/

/obj/item/device/rad_laser
	name = "health analyzer"
	icon_state = "health"
	item_state = "analyzer"
	desc = "A hand-held body scanner able to distinguish vital signs of the subject. A strange microlaser is hooked on to the scanning end."
	flags = CONDUCT
	slot_flags = SLOT_BELT
	throwforce = 3
	w_class = 1
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=400)
	origin_tech = "magnets=3;biotech=5;syndicate=3"
	var/intensity = 5 // how much damage the radiation does
	var/wavelength = 10 // time it takes for the radiation to kick in, in seconds
	var/used = 0 // is it cooling down?

/obj/item/device/rad_laser/attack(mob/living/M, mob/living/user)
	if(!used)
		add_logs(user, M, "irradiated", src)
		user.visible_message("[user] has analyzed [M]'s vitals.")
		var/cooldown = round(max(100,(((intensity*8)-(wavelength/2))+(intensity*2))*10))
		used = 1
		icon_state = "health1"
		handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength
		spawn((wavelength+(intensity*4))*10)
			if(M)
				if(intensity >= 5)
					M.apply_effect(round(intensity/1.5), PARALYZE)
				M.rad_act(intensity*10)
	else
		user << "The radioactive microlaser is still recharging."

/obj/item/device/rad_laser/proc/handle_cooldown(cooldown)
	spawn(cooldown)
		used = 0
		icon_state = "health"

/obj/item/device/rad_laser/attack_self(mob/user)
	..()
	interact(user)

/obj/item/device/rad_laser/interact(mob/user)
	user.set_machine(src)

	var/cooldown = round(max(10,((intensity*8)-(wavelength/2))+(intensity*2)))
	var/dat = {"
	Radiation Intensity: -- [intensity] ++

	Radiation Wavelength: -- [(wavelength+(intensity*4))] ++

	Laser Cooldown: [cooldown] Seconds

	"}

	var/datum/browser/popup = new(user, "radlaser", "Radioactive Microlaser Interface", 400, 240)
	popup.set_content(dat)
	popup.open()

/obj/item/device/rad_laser/Topic(href, href_list)
	if(!usr.canUseTopic(src))
		return 1

	usr.set_machine(src)

	if(href_list["radint"])
		var/amount = text2num(href_list["radint"])
		amount += intensity
		intensity = max(1,(min(10,amount)))

	else if(href_list["radwav"])
		var/amount = text2num(href_list["radwav"])
		amount += wavelength
		wavelength = max(1,(min(120,amount)))

	attack_self(usr)
	add_fingerprint(usr)
	return

/obj/item/device/shadowcloak
	name = "cloaker belt"
	desc = "Makes you invisible for short periods of time. Recharges in darkness."
	icon = 'icons/obj/clothing/belts.dmi'
	icon_state = "utilitybelt"
	item_state = "utility"
	slot_flags = SLOT_BELT
	attack_verb = list("whipped", "lashed", "disciplined")

	var/mob/living/carbon/human/user = null
	var/charge = 300
	var/max_charge = 300
	var/on = 0
	var/old_alpha = 0
	actions_types = list(/datum/action/item_action/toggle)

/obj/item/device/shadowcloak/ui_action_click(mob/user)
	if(user.get_item_by_slot(slot_belt) == src)
		if(!on)
			Activate(usr)
		else
			Deactivate()
	return

/obj/item/device/shadowcloak/item_action_slot_check(slot, mob/user)
	if(slot == slot_belt)
		return 1

/obj/item/device/shadowcloak/proc/Activate(mob/living/carbon/human/user)
	if(!user)
		return
	user << "You activate [src]."
	src.user = user
	SSobj.processing |= src
	old_alpha = user.alpha
	on = 1

/obj/item/device/shadowcloak/proc/Deactivate()
	user << "You deactivate [src]."
	SSobj.processing.Remove(src)
	if(user)
		user.alpha = old_alpha
	on = 0
	user = null

/obj/item/device/shadowcloak/dropped(mob/user)
	..()
	if(user && user.get_item_by_slot(slot_belt) != src)
		Deactivate()

/obj/item/device/shadowcloak/process()
	if(user.get_item_by_slot(slot_belt) != src)
		Deactivate()
		return
	var/turf/T = get_turf(src)
	if(on)
		var/lumcount = T.get_lumcount()
		if(lumcount > 3)
			charge = max(0,charge - 25)//Quick decrease in light
		else
			charge = min(max_charge,charge + 50) //Charge in the dark
		animate(user,alpha = Clamp(255 - charge,0,255),time = 10)


code:
/obj/item/device/transfer_valve
	icon = 'icons/obj/assemblies.dmi'
	name = "tank transfer valve"
	icon_state = "valve_1"
	item_state = "ttv"
	desc = "Regulates the transfer of air between two tanks"
	var/obj/item/weapon/tank/tank_one
	var/obj/item/weapon/tank/tank_two
	var/obj/item/device/attached_device
	var/mob/attacher = null
	var/valve_open = 0
	var/toggle = 1

/obj/item/device/transfer_valve/IsAssemblyHolder()
	return 1

/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params)
	if(istype(item, /obj/item/weapon/tank))
		if(tank_one && tank_two)
			user << "There are already two tanks attached, remove one first!"
			return

		if(!tank_one)
			if(!user.unEquip(item))
				return
			tank_one = item
			item.loc = src
			user << "You attach the tank to the transfer valve."
			if(item.w_class > w_class)
				w_class = item.w_class
		else if(!tank_two)
			if(!user.unEquip(item))
				return
			tank_two = item
			item.loc = src
			user << "You attach the tank to the transfer valve."
			if(item.w_class > w_class)
				w_class = item.w_class

		update_icon()
//TODO: Have this take an assemblyholder
	else if(isassembly(item))
		var/obj/item/device/assembly/A = item
		if(A.secured)
			user << "The device is secured."
			return
		if(attached_device)
			user << "There is already a device attached to the valve, remove it first!"
			return
		user.remove_from_mob(item)
		attached_device = A
		A.loc = src
		user << "You attach the [item] to the valve controls and secure it."
		A.holder = src
		A.toggle_secure()	//this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).

		bombers += "[key_name(user)] attached a [item] to a transfer valve."
		message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.")
		log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
		attacher = user
	return

/obj/item/device/transfer_valve/attack_self(mob/user)
	user.set_machine(src)
	var/dat = {" Valve properties:

  Attachment one: [tank_one] [tank_one ? "Remove" : ""]

  Attachment two: [tank_two] [tank_two ? "Remove" : ""]

  Valve attachment: [attached_device ? "[attached_device]" : "None"] [attached_device ? "Remove" : ""]

  Valve status:  [ valve_open ? "Closed Open" : "Closed Open"]"}

	var/datum/browser/popup = new(user, "trans_valve", name)
	popup.set_content(dat)
	popup.open()
	return

/obj/item/device/transfer_valve/Topic(href, href_list)
	..()
	if ( usr.stat || usr.restrained() )
		return
	if (src.loc == usr)
		if(tank_one && href_list["tankone"])
			split_gases()
			valve_open = 0
			tank_one.loc = get_turf(src)
			tank_one = null
			update_icon()
			if((!tank_two || tank_two.w_class < 4) && (w_class > 3))
				w_class = 3
		else if(tank_two && href_list["tanktwo"])
			split_gases()
			valve_open = 0
			tank_two.loc = get_turf(src)
			tank_two = null
			update_icon()
			if((!tank_one || tank_one.w_class < 4) && (w_class > 3))
				w_class = 3
		else if(href_list["open"])
			toggle_valve()
		else if(attached_device)
			if(href_list["rem_device"])
				attached_device.loc = get_turf(src)
				attached_device:holder = null
				attached_device = null
				update_icon()
			if(href_list["device"])
				attached_device.attack_self(usr)

		src.attack_self(usr)
		src.add_fingerprint(usr)
		return
	return

/obj/item/device/transfer_valve/proc/process_activation(obj/item/device/D)
	if(toggle)
		toggle = 0
		toggle_valve()
		spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever
			toggle = 1

/obj/item/device/transfer_valve/update_icon()
	overlays.Cut()
	underlays = null

	if(!tank_one && !tank_two && !attached_device)
		icon_state = "valve_1"
		return
	icon_state = "valve"

	if(tank_one)
		overlays += "[tank_one.icon_state]"
	if(tank_two)
		var/icon/J = new(icon, icon_state = "[tank_two.icon_state]")
		J.Shift(WEST, 13)
		underlays += J
	if(attached_device)
		overlays += "device"

/obj/item/device/transfer_valve/proc/merge_gases()
	tank_two.air_contents.volume += tank_one.air_contents.volume
	var/datum/gas_mixture/temp
	temp = tank_one.air_contents.remove_ratio(1)
	tank_two.air_contents.merge(temp)

/obj/item/device/transfer_valve/proc/split_gases()
	if (!valve_open || !tank_one || !tank_two)
		return
	var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
	var/datum/gas_mixture/temp
	temp = tank_two.air_contents.remove_ratio(ratio1)
	tank_one.air_contents.merge(temp)
	tank_two.air_contents.volume -=  tank_one.air_contents.volume

	/*
	Exadv1: I know this isn't how it's going to work, but this was just to check
	it explodes properly when it gets a signal (and it does).
	*/

/obj/item/device/transfer_valve/proc/toggle_valve()
	if(!valve_open && tank_one && tank_two)
		valve_open = 1
		var/turf/bombturf = get_turf(src)
		var/area/A = get_area(bombturf)

		var/attachment = "no device"
		if(attached_device)
			if(istype(attached_device, /obj/item/device/assembly/signaler))
				attachment = "[attached_device]"
			else
				attachment = attached_device

		var/attacher_name = ""
		if(!attacher)
			attacher_name = "Unknown"
		else
			attacher_name = "[key_name_admin(attacher)]"

		var/log_str1 = "Bomb valve opened in "
		var/log_str2 = "with [attachment] attacher: [attacher_name]"

		var/log_attacher = ""
		if(attacher)
			log_attacher = "(?) (FLW)"

		var/mob/mob = get_mob_by_key(src.fingerprintslast)
		var/last_touch_info = ""
		if(mob)
			last_touch_info = "(?) (FLW)"

		var/log_str3 = " Last touched by: [key_name_admin(mob)]"

		var/bomb_message = "[log_str1] [A.name]  [log_str2][log_attacher] [log_str3][last_touch_info]"

		bombers += bomb_message

		message_admins(bomb_message, 0, 1)
		log_game("[log_str1] [A.name]([A.x],[A.y],[A.z]) [log_str2] [log_str3]")
		merge_gases()
		spawn(20) // In case one tank bursts
			for (var/i=0,i<5,i++)
				src.update_icon()
				sleep(10)
			src.update_icon()

	else if(valve_open && tank_one && tank_two)
		split_gases()
		valve_open = 0
		src.update_icon()

// this doesn't do anything but the timer etc. expects it to be here
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
/obj/item/device/transfer_valve/proc/c_state()
	return


code:
/obj/item/documents
	name = "secret documents"
	desc = "\"Top Secret\" documents."
	icon = 'icons/obj/bureaucracy.dmi'
	icon_state = "docs_generic"
	item_state = "paper"
	throwforce = 0
	w_class = 1
	throw_range = 1
	throw_speed = 1
	layer = 4
	pressure_resistance = 1

/obj/item/documents/nanotrasen
	desc = "\"Top Secret\" Nanotrasen documents, filled with complex diagrams and lists of names, dates and coordinates."
	icon_state = "docs_verified"

/obj/item/documents/syndicate
	desc = "\"Top Secret\" documents detailing sensitive Syndicate operational intelligence."

/obj/item/documents/syndicate/red
	name = "red secret documents"
	desc = "\"Top Secret\" documents detailing sensitive Syndicate operational intelligence. These documents are verified with a red wax seal."
	icon_state = "docs_red"

/obj/item/documents/syndicate/blue
	name = "blue secret documents"
	desc = "\"Top Secret\" documents detailing sensitive Syndicate operational intelligence. These documents are verified with a blue wax seal."
	icon_state = "docs_blue"

/obj/item/documents/photocopy
	desc = "A copy of some top-secret documents. Nobody will notice they aren't the originals... right?"
	var/forgedseal = 0

/obj/item/documents/photocopy/attackby(obj/item/O, mob/user, params)
	if(istype(O, /obj/item/toy/crayon/red) || istype(O, /obj/item/toy/crayon/blue))
		if (forgedseal)
			user << "You have already forged a seal on [src]!"
		else
			var/obj/item/toy/crayon/C = O
			name = "[C.colourName] secret documents"
			icon_state = "docs_[C.colourName]"
			forgedseal = 1
			user << "You forge the official seal with a [C.colourName] crayon. No one will notice... right?"
			update_icon()


code:
/obj/item/latexballon
	name = "latex glove"
	desc = "" //todo
	icon_state = "latexballon"
	item_state = "lgloves"
	force = 0
	throwforce = 0
	w_class = 1
	throw_speed = 1
	throw_range = 7
	var/state
	var/datum/gas_mixture/air_contents = null

/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank, mob/user)
	if (icon_state == "latexballon_bursted")
		return
	icon_state = "latexballon_blow"
	item_state = "latexballon"
	user.update_inv_r_hand()
	user.update_inv_l_hand()
	user << "You blow up [src] with [tank]."
	air_contents = tank.remove_air_volume(3)

/obj/item/latexballon/proc/burst()
	if (!air_contents || icon_state != "latexballon_blow")
		return
	playsound(src, 'sound/weapons/Gunshot.ogg', 100, 1)
	icon_state = "latexballon_bursted"
	item_state = "lgloves"
	if(istype(src.loc, /mob/living))
		var/mob/living/user = src.loc
		user.update_inv_r_hand()
		user.update_inv_l_hand()
	loc.assume_air(air_contents)

/obj/item/latexballon/ex_act(severity, target)
	burst()
	switch(severity)
		if (1)
			qdel(src)
		if (2)
			if (prob(50))
				qdel(src)

/obj/item/latexballon/bullet_act()
	burst()

/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume)
	if(temperature > T0C+100)
		burst()
	return

/obj/item/latexballon/attackby(obj/item/W, mob/user, params)
	if(istype(W, /obj/item/weapon/tank))
		var/obj/item/weapon/tank/T = W
		blow(T, user)
		return
	if (is_sharp(W) || W.is_hot() || is_pointed(W))
		burst()


code:
//Items for nuke theft traitor objective

//the nuke core - objective item
/obj/item/nuke_core
	name = "plutonium core"
	desc = "Extremely radioactive. Wear goggles."
	icon = 'icons/obj/nuke_tools.dmi'
	icon_state = "plutonium_core"
	item_state = "plutoniumcore"
	var/pulse = 0
	var/cooldown = 0

/obj/item/nuke_core/New()
	SSobj.processing += src

/obj/item/nuke_core/attackby(obj/item/nuke_core_container/container, mob/user)
	if(istype(container))
		container.load(src, user)
	else
		..()

/obj/item/nuke_core/process()
	if(cooldown < world.time - 60)
		cooldown = world.time
		flick("plutonium_core_pulse", src)
		radiation_pulse(get_turf(src), 1, 4, 40, 1)

//nuke core box, for carrying the core
/obj/item/nuke_core_container
	name = "nuke core container"
	desc = "Solid container for radioactive objects."
	icon = 'icons/obj/nuke_tools.dmi'
	icon_state = "core_container_empty"
	item_state = "tile"
	var/obj/item/nuke_core/core = null

/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/ncore, mob/user)
	if(core || !istype(ncore))
		return 0
	ncore.loc = src
	core = ncore
	icon_state = "core_container_loaded"
	user << "Container is sealing..."
	spawn(50)
		SSobj.processing -= core
		icon_state = "core_container_sealed"
		playsound(loc, 'sound/items/Deconstruct.ogg', 100, 1)
		if(loc == user)
			user << "Container is sealed, the radiation is contained."
	return 1

/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user)
	if(istype(core))
		if(!user.unEquip(core))
			user << "The [core] is stuck to your hand!"
			return
		else
			load(core, user)
	else
		..()

//snowflake screwdriver, works as a key to start nuke theft, traitor only
/obj/item/weapon/screwdriver/nuke
	name = "screwdriver"
	desc = "A screwdriver with an ultra thin tip."
	icon = 'icons/obj/nuke_tools.dmi'
	icon_state = "screwdriver_nuke"
	item_state = "screwdriver_nuke"
	toolspeed = 2

/obj/item/weapon/screwdriver/nuke/New()
//to skip screwdriver icon update

/obj/item/weapon/paper/nuke_instructions
	info = "How to break into a Nanotrasen self-destruct terminal and remove its plutonium core:
\

\

Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel
\

Dislodge and remove the front panel with a crowbar
\

Cut the inner metal plate with a welding tool
\

Pry off the inner plate with a crowbar to expose the radioactive core
\

Use the core container to remove the plutonium core; the container will take some time to seal
\

???
"


code:
///AI Upgrades

//Malf Picker
/obj/item/device/malf_upgrade
	name = "combat software upgrade"
	desc = "A highly illegal, highly dangerous upgrade for artificial intelligence units, granting them a variety of powers as well as the ability to hack APCs."
	icon = 'icons/obj/module.dmi'
	icon_state = "datadisk3"

/obj/item/device/malf_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user)
	if(!istype(AI))
		return
	if(AI.malf_picker)
		AI.malf_picker.processing_time += 50
		AI << "[user] has attempted to upgrade you with combat software that you already possess. You gain 50 points to spend on Malfunction Modules instead."
	else
		AI << "[user] has upgraded you with combat software!"
		AI.add_malf_picker()
	user << "You upgrade [AI]. [src] is consumed in the process."
	qdel(src)

//Lipreading
/obj/item/device/surveillance_upgrade
	name = "surveillance software upgrade"
	desc = "A software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading."
	icon = 'icons/obj/module.dmi'
	icon_state = "datadisk3"

/obj/item/device/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user)
	if(!istype(AI))
		return
	if(AI.eyeobj)
		AI.eyeobj.relay_speech = TRUE
		AI << "[user] has upgraded you with surveillance software!"
		AI << "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations."
	user << "You upgrade [AI]. [src] is consumed in the process."
	qdel(src)


code:
/**********************************************************************
						Cyborg Spec Items
***********************************************************************/
/obj/item/borg
	icon = 'icons/mob/robot_items.dmi'

/obj/item/borg/stun
	name = "electrically-charged arm"
	icon_state = "elecarm"

/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
	if(!user.cell.use(30)) return

	M.Weaken(5)
	M.apply_effect(STUTTER, 5)
	M.Stun(5)

	M.visible_message("[user] has prodded [M] with [src]!", \
					"[user] has prodded you with [src]!")
	add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")

/obj/item/borg/charger
	name = "power connector"
	icon_state = "charger_draw"
	flags = NOBLUDGEON
	var/mode = "draw"
	var/list/charge_machines = list(/obj/machinery/cell_charger, /obj/machinery/recharger,
		/obj/machinery/recharge_station, /obj/machinery/mech_bay_recharge_port)
	var/list/charge_items = list(/obj/item/weapon/stock_parts/cell, /obj/item/weapon/gun/energy,
		)

/obj/item/borg/charger/update_icon()
	..()
	icon_state = "charger_[mode]"

/obj/item/borg/charger/attack_self(mob/user)
	if(mode == "draw")
		mode = "charge"
	else
		mode = "draw"
	user << "You toggle [src] to \"[mode]\" mode."
	update_icon()

/obj/item/borg/charger/afterattack(obj/item/target, mob/living/silicon/robot/user, proximity_flag)
	if(!proximity_flag || !isrobot(user))
		return
	if(mode == "draw")
		if(is_type_in_list(target, charge_machines))
			var/obj/machinery/M = target
			if((M.stat & (NOPOWER|BROKEN)) || !M.anchored)
				user << "[M] is unpowered!"
				return

			user << "You connect to [M]'s power line..."
			while(do_after(user, 15, target = M, progress = 0))
				if(!user || !user.cell || mode != "draw")
					return

				if((M.stat & (NOPOWER|BROKEN)) || !M.anchored)
					break

				if(!user.cell.give(150))
					break

				M.use_power(200)

			user << "You stop charging youself."

		else if(is_type_in_list(target, charge_items))
			var/obj/item/weapon/stock_parts/cell/cell = target
			if(!istype(cell))
				cell = locate(/obj/item/weapon/stock_parts/cell) in target
			if(!cell)
				user << "[target] has no power cell!"
				return

			if(istype(target, /obj/item/weapon/gun/energy))
				var/obj/item/weapon/gun/energy/E = target
				if(!E.can_charge)
					user << "[target] has no power port!"
					return

			if(!cell.charge)
				user << "[target] has no power!"

			user << "You connect to [target]'s power port..."

			while(do_after(user, 15, target = target, progress = 0))
				if(!user || !user.cell || mode != "draw")
					return

				if(!cell || !target)
					return

				if(cell != target && cell.loc != target)
					return

				var/draw = min(cell.charge, cell.chargerate*0.5, user.cell.maxcharge-user.cell.charge)
				if(!cell.use(draw))
					break
				if(!user.cell.give(draw))
					break
				target.update_icon()

			user << "You stop charging youself."

	else if(is_type_in_list(target, charge_items))
		var/obj/item/weapon/stock_parts/cell/cell = target
		if(!istype(cell))
			cell = locate(/obj/item/weapon/stock_parts/cell) in target
		if(!cell)
			user << "[target] has no power cell!"
			return

		if(istype(target, /obj/item/weapon/gun/energy))
			var/obj/item/weapon/gun/energy/E = target
			if(!E.can_charge)
				user << "[target] has no power port!"
				return

		if(cell.charge >= cell.maxcharge)
			user << "[target] is already charged!"

		user << "You connect to [target]'s power port..."

		while(do_after(user, 15, target = target, progress = 0))
			if(!user || !user.cell || mode != "charge")
				return

			if(!cell || !target)
				return

			if(cell != target && cell.loc != target)
				return

			var/draw = min(user.cell.charge, cell.chargerate*0.5, cell.maxcharge-cell.charge)
			if(!user.cell.use(draw))
				break
			if(!cell.give(draw))
				break
			target.update_icon()

		user << "You stop charging [target]."

/**********************************************************************
						HUD/SIGHT things
***********************************************************************/
/obj/item/borg/sight
	var/sight_mode = null

/obj/item/borg/sight/xray
	name = "\proper x-ray Vision"
	icon = 'icons/obj/decals.dmi'
	icon_state = "securearea"
	sight_mode = BORGXRAY

/obj/item/borg/sight/thermal
	name = "\proper thermal vision"
	sight_mode = BORGTHERM
	icon_state = "thermal"

/obj/item/borg/sight/meson
	name = "\proper meson vision"
	sight_mode = BORGMESON
	icon_state = "meson"

/obj/item/borg/sight/material
	name = "\proper material vision"
	sight_mode = BORGMATERIAL
	icon_state = "material"

/obj/item/borg/sight/hud
	name = "hud"
	var/obj/item/clothing/glasses/hud/hud = null

/obj/item/borg/sight/hud/med
	name = "medical hud"
	icon_state = "healthhud"

/obj/item/borg/sight/hud/med/New()
	..()
	hud = new /obj/item/clothing/glasses/hud/health(src)
	return

/obj/item/borg/sight/hud/sec
	name = "security hud"
	icon_state = "securityhud"

/obj/item/borg/sight/hud/sec/New()
	..()
	hud = new /obj/item/clothing/glasses/hud/security(src)
	return


code:
/obj/item/robot_parts
	name = "robot parts"
	icon = 'icons/obj/robot_parts.dmi'
	item_state = "buildpipe"
	icon_state = "blank"
	flags = CONDUCT
	slot_flags = SLOT_BELT

/obj/item/robot_parts/l_arm
	name = "cyborg left arm"
	desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
	icon_state = "l_arm"

/obj/item/robot_parts/r_arm
	name = "cyborg right arm"
	desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
	icon_state = "r_arm"

/obj/item/robot_parts/l_leg
	name = "cyborg left leg"
	desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
	icon_state = "l_leg"

/obj/item/robot_parts/r_leg
	name = "cyborg right leg"
	desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
	icon_state = "r_leg"

/obj/item/robot_parts/chest
	name = "cyborg torso"
	desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
	icon_state = "chest"
	var/wired = 0
	var/obj/item/weapon/stock_parts/cell/cell = null

/obj/item/robot_parts/head
	name = "cyborg head"
	desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
	icon_state = "head"
	var/obj/item/device/assembly/flash/handheld/flash1 = null
	var/obj/item/device/assembly/flash/handheld/flash2 = null

/obj/item/robot_parts/robot_suit
	name = "cyborg endoskeleton"
	desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
	icon_state = "robo_suit"
	var/obj/item/robot_parts/l_arm/l_arm = null
	var/obj/item/robot_parts/r_arm/r_arm = null
	var/obj/item/robot_parts/l_leg/l_leg = null
	var/obj/item/robot_parts/r_leg/r_leg = null
	var/obj/item/robot_parts/chest/chest = null
	var/obj/item/robot_parts/head/head = null

	var/created_name = ""
	var/mob/living/silicon/ai/forced_ai
	var/locomotion = 1
	var/lawsync = 1
	var/aisync = 1
	var/panel_locked = 1

/obj/item/robot_parts/robot_suit/New()
	..()
	src.updateicon()

/obj/item/robot_parts/robot_suit/proc/updateicon()
	src.overlays.Cut()
	if(src.l_arm)
		src.overlays += "l_arm+o"
	if(src.r_arm)
		src.overlays += "r_arm+o"
	if(src.chest)
		src.overlays += "chest+o"
	if(src.l_leg)
		src.overlays += "l_leg+o"
	if(src.r_leg)
		src.overlays += "r_leg+o"
	if(src.head)
		src.overlays += "head+o"

/obj/item/robot_parts/robot_suit/proc/check_completion()
	if(src.l_arm && src.r_arm)
		if(src.l_leg && src.r_leg)
			if(src.chest && src.head)
				feedback_inc("cyborg_frames_built",1)
				return 1
	return 0

/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user, params)
	..()
	if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
		var/obj/item/stack/sheet/metal/M = W
		if (M.use(1))
			var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly
			B.loc = get_turf(src)
			user << "You arm the robot frame."
			if (user.get_inactive_hand()==src)
				user.unEquip(src)
				user.put_in_inactive_hand(B)
			qdel(src)
		else
			user << "You need one sheet of metal to start building ED-209!"
			return
	if(istype(W, /obj/item/robot_parts/l_leg))
		if(src.l_leg)
			return
		if(!user.unEquip(W))
			return
		W.loc = src
		src.l_leg = W
		src.updateicon()

	if(istype(W, /obj/item/robot_parts/r_leg))
		if(src.r_leg)
			return
		if(!user.unEquip(W))
			return
		W.loc = src
		src.r_leg = W
		src.updateicon()

	if(istype(W, /obj/item/robot_parts/l_arm))
		if(src.l_arm)
			return
		if(!user.unEquip(W))
			return
		W.loc = src
		src.l_arm = W
		src.updateicon()

	if(istype(W, /obj/item/robot_parts/r_arm))
		if(src.r_arm)
			return
		if(!user.unEquip(W))
			return
		W.loc = src
		src.r_arm = W
		src.updateicon()

	if(istype(W, /obj/item/robot_parts/chest))
		if(src.chest)
			return
		if(W:wired && W:cell)
			if(!user.unEquip(W))
				return
			W.loc = src
			src.chest = W
			src.updateicon()
		else if(!W:wired)
			user << "You need to attach wires to it first!"
		else
			user << "You need to attach a cell to it first!"

	if(istype(W, /obj/item/robot_parts/head))
		if(src.head)
			return
		if(W:flash2 && W:flash1)
			if(!user.unEquip(W))
				return
			W.loc = src
			src.head = W
			src.updateicon()
		else
			user << "You need to attach a flash to it first!"

	if (istype(W, /obj/item/device/multitool))
		if(check_completion())
			Interact(user)
		else
			user << "The endoskeleton must be assembled before debugging can begin!"

	if(istype(W, /obj/item/device/mmi))
		var/obj/item/device/mmi/M = W
		if(check_completion())
			if(!istype(loc,/turf))
				user << "You can't put the MMI in, the frame has to be standing on the ground to be perfectly precise!"
				return
			if(!M.brainmob)
				user << "Sticking an empty MMI into the frame would sort of defeat the purpose!"
				return

			var/mob/living/carbon/brain/BM = M.brainmob
			if(!BM.key || !BM.mind)
				user << "The mmi indicates that their mind is completely unresponsive; there's no point!"
				return

			if(!BM.client) //braindead
				user << "The mmi indicates that their mind is currently inactive; it might change!"
				return

			if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
				user << "Sticking a dead brain into the frame would sort of defeat the purpose!"
				return

			if(jobban_isbanned(BM, "Cyborg"))
				user << "This MMI does not seem to fit!"
				return

			var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
			if(!O)
				return

			if(!user.unEquip(W))
				return

			if(M.syndiemmi)
				aisync = 0
				lawsync = 0
				O.laws = new /datum/ai_laws/syndicate_override

			O.invisibility = 0
			//Transfer debug settings to new mob
			O.custom_name = created_name
			O.locked = panel_locked
			if(!aisync)
				lawsync = 0
				O.connected_ai = null
			else
				O.notify_ai(1)
				if(forced_ai)
					O.connected_ai = forced_ai
			if(!lawsync && !M.syndiemmi)
				O.lawupdate = 0
				O.make_laws()

			ticker.mode.remove_antag_for_borging(BM.mind)
			BM.mind.transfer_to(O)

			if(O.mind && O.mind.special_role)
				O.mind.store_memory("As a cyborg, you must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead.")
				O << "You have been robotized!"
				O << "You must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead."

			O.job = "Cyborg"

			O.cell = chest.cell
			chest.cell.loc = O
			chest.cell = null
			W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
			if(O.mmi) //we delete the mmi created by robot/New()
				qdel(O.mmi)
			O.mmi = W //and give the real mmi to the borg.
			O.updatename()

			feedback_inc("cyborg_birth",1)

			src.loc = O
			O.robot_suit = src

			if(!locomotion)
				O.lockcharge = 1
				O.update_canmove()
				O << "Error: Servo motors unresponsive."

		else
			user << "The MMI must go in after everything else!"

	if(istype(W,/obj/item/weapon/pen))
		user << "You need to use a multitool to name [src]!"
	return

/obj/item/robot_parts/robot_suit/proc/Interact(mob/user)
			var/t1 = text("Designation: [(created_name ? "[created_name]" : "Default Cyborg")]
\n",src)
			t1 += text("Master AI: [(forced_ai ? "[forced_ai.name]" : "Automatic")]

\n",src)

			t1 += text("LawSync Port: [(lawsync ? "Open" : "Closed")]
\n",src)
			t1 += text("AI Connection Port: [(aisync ? "Open" : "Closed")]
\n",src)
			t1 += text("Servo Motor Functions: [(locomotion ? "Unlocked" : "Locked")]
\n",src)
			t1 += text("Panel Lock: [(panel_locked ? "Engaged" : "Disengaged")]
\n",src)
			var/datum/browser/popup = new(user, "robotdebug", "Cyborg Boot Debug", 310, 220)
			popup.set_content(t1)
			popup.open()

/obj/item/robot_parts/robot_suit/Topic(href, href_list)
	if(usr.lying || usr.stat || usr.stunned || !Adjacent(usr))
		return

	var/mob/living/living_user = usr
	var/obj/item/item_in_hand = living_user.get_active_hand()
	if(!istype(item_in_hand, /obj/item/device/multitool))
		living_user << "You need a multitool!"
		return

	if(href_list["Name"])
		var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", src.created_name),1)
		if(!in_range(src, usr) && src.loc != usr)
			return
		if(new_name)
			created_name = new_name
		else
			created_name = ""

	else if(href_list["Master"])
		forced_ai = select_active_ai(usr)
		if(!forced_ai)
			usr << "No active AIs detected."

	else if(href_list["Law"])
		lawsync = !lawsync
	else if(href_list["AI"])
		aisync = !aisync
	else if(href_list["Loco"])
		locomotion = !locomotion
	else if(href_list["Panel"])
		panel_locked = !panel_locked

	add_fingerprint(usr)
	Interact(usr)
	return

/obj/item/robot_parts/chest/attackby(obj/item/W, mob/user, params)
	..()
	if(istype(W, /obj/item/weapon/stock_parts/cell))
		if(src.cell)
			user << "You have already inserted a cell!"
			return
		else
			if(!user.unEquip(W))
				return
			W.loc = src
			src.cell = W
			user << "You insert the cell."
	if(istype(W, /obj/item/stack/cable_coil))
		if(src.wired)
			user << "You have already inserted wire!"
			return
		var/obj/item/stack/cable_coil/coil = W
		if (coil.use(1))
			src.wired = 1
			user << "You insert the wire."
		else
			user << "You need one length of coil to wire it!"
	return

/obj/item/robot_parts/head/attackby(obj/item/W, mob/user, params)
	..()
	if(istype(W, /obj/item/device/assembly/flash/handheld))
		var/obj/item/device/assembly/flash/handheld/F = W
		if(src.flash1 && src.flash2)
			user << "You have already inserted the eyes!"
			return
		else if(F.crit_fail)
			user << "You can't use a broken flash!"
			return
		else
			if(!user.unEquip(W))
				return
			F.loc = src
			if(src.flash1)
				src.flash2 = F
			else
				src.flash1 = F
			user << "You insert the flash into the eye socket."
	return


code:
// robot_upgrades.dm
// Contains various borg upgrades.

/obj/item/borg/upgrade
	name = "borg upgrade module."
	desc = "Protected by FRM."
	icon = 'icons/obj/module.dmi'
	icon_state = "cyborg_upgrade"
	origin_tech = "programming=4"
	var/locked = 0
	var/installed = 0
	var/require_module = 0
	var/module_type = null

/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R)
	if(R.stat == DEAD)
		usr << "[src] will not function on a deceased cyborg."
		return 1
	if(module_type && !istype(R.module, module_type))
		R << "Upgrade mounting error!  No suitable hardpoint detected!"
		usr << "There's no mounting point for the module!"
		return 1

/obj/item/borg/upgrade/reset
	name = "cyborg module reset board"
	desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the cyborg."
	icon_state = "cyborg_upgrade1"
	require_module = 1

/obj/item/borg/upgrade/reset/action(mob/living/silicon/robot/R)
	if(..())
		return

	R.notify_ai(2)

	R.uneq_all()
	R.hands.icon_state = "nomod"
	R.icon_state = "robot"
	qdel(R.module)
	R.module = null

	R.modtype = "robot"
	R.designation = "Default"
	R.updatename("Default")

	R.update_icons()
	R.update_headlamp()

	R.speed = 0 // Remove upgrades.
	R.ionpulse = FALSE
	R.magpulse = FALSE

	R.status_flags |= CANPUSH

	return 1

/obj/item/borg/upgrade/rename
	name = "cyborg reclassification board"
	desc = "Used to rename a cyborg."
	icon_state = "cyborg_upgrade1"
	var/heldname = "default name"

/obj/item/borg/upgrade/rename/attack_self(mob/user)
	heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)

/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R)
	if(..())
		return

	R.fully_replace_character_name(R.name, heldname)

	return 1

/obj/item/borg/upgrade/restart
	name = "cyborg emergency reboot module"
	desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online."
	icon_state = "cyborg_upgrade1"

/obj/item/borg/upgrade/restart/action(mob/living/silicon/robot/R)
	if(R.health < 0)
		usr << "You have to repair the cyborg before using this module!"
		return 0

	if(!R.key)
		for(var/mob/dead/observer/ghost in player_list)
			if(ghost.mind && ghost.mind.current == R)
				R.key = ghost.key

	R.revive()

	return 1

/obj/item/borg/upgrade/vtec
	name = "cyborg VTEC module"
	desc = "Used to kick in a cyborg's VTEC systems, increasing their speed."
	icon_state = "cyborg_upgrade2"
	require_module = 1
	origin_tech = "engineering=4;materials=5"

/obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R)
	if(..())
		return
	if(R.speed < 0)
		R << "A VTEC unit is already installed!"
		usr << "There's no room for another VTEC unit!"
		return

	R.speed = -2 // Gotta go fast.

	return 1

/obj/item/borg/upgrade/disablercooler
	name = "cyborg rapid disabler cooling module"
	desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
	icon_state = "cyborg_upgrade3"
	require_module = 1
	module_type = /obj/item/weapon/robot_module/security
	origin_tech = "engineering=4;powerstorage=4"

/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R)
	if(..())
		return

	var/obj/item/weapon/gun/energy/disabler/cyborg/T = locate() in R.module.modules
	if(!T)
		usr << "There's no disabler in this unit!"
		return
	if(T.charge_delay <= 2)
		R << "A cooling unit is already installed!"
		usr << "There's no room for another cooling unit!"
		return

	T.charge_delay = max(2 , T.charge_delay - 4)

	return 1

/obj/item/borg/upgrade/thrusters
	name = "ion thruster upgrade"
	desc = "A energy-operated thruster system for cyborgs."
	icon_state = "cyborg_upgrade3"
	origin_tech = "engineering=4;powerstorage=4"

/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R)
	if(..())
		return

	if(R.ionpulse)
		usr << "This unit already has ion thrusters installed!"
		return

	R.ionpulse = TRUE
	return 1

/obj/item/borg/upgrade/ddrill
	name = "mining cyborg diamond drill"
	desc = "A diamond drill replacement for the mining module's standard drill."
	icon_state = "cyborg_upgrade3"
	require_module = 1
	module_type = /obj/item/weapon/robot_module/miner
	origin_tech = "engineering=5;materials=5"

/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R)
	if(..())
		return

	for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module.modules)
		qdel(D)
	for(var/obj/item/weapon/shovel/S in R.module.modules)
		qdel(S)

	R.module.modules += new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
	R.module.rebuild()

	return 1

/obj/item/borg/upgrade/soh
	name = "mining cyborg satchel of holding"
	desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
	icon_state = "cyborg_upgrade3"
	require_module = 1
	module_type = /obj/item/weapon/robot_module/miner
	origin_tech = "engineering=5;materials=5;bluespace=3"

/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R)
	if(..())
		return

	for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module.modules)
		qdel(S)

	R.module.modules += new /obj/item/weapon/storage/bag/ore/holding(R.module)
	R.module.rebuild()

	return 1

/obj/item/borg/upgrade/syndicate
	name = "illegal equipment module"
	desc = "Unlocks the hidden, deadlier functions of a cyborg"
	icon_state = "cyborg_upgrade3"
	require_module = 1
	origin_tech = "combat=4;syndicate=2"

/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R)
	if(..())
		return

	if(R.emagged)
		return

	R.SetEmagged(1)

	return 1

/obj/item/borg/upgrade/selfrepair
	name = "self-repair module"
	desc = "This module will repair the cyborg over time."
	icon_state = "cyborg_upgrade5"
	require_module = 1
	var/repair_amount = -1
	var/repair_tick = 1
	var/msg_cooldown = 0
	var/on = 0
	var/powercost = 10
	var/mob/living/silicon/robot/cyborg

/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R)
	if(..())
		return

	var/obj/item/borg/upgrade/selfrepair/U = locate() in R
	if(U)
		usr << "This unit is already equipped with a self-repair module."
		return 0

	cyborg = R
	icon_state = "selfrepair_off"
	var/datum/action/A = new /datum/action/item_action/toggle(src)
	A.Grant(R)
	return 1

/obj/item/borg/upgrade/selfrepair/ui_action_click()
	on = !on
	if(on)
		cyborg << "You activate the self-repair module."
		SSobj.processing |= src
	else
		cyborg << "You deactivate the self-repair module."
		SSobj.processing -= src
	update_icon()

/obj/item/borg/upgrade/selfrepair/update_icon()
	if(cyborg)
		icon_state = "selfrepair_[on ? "on" : "off"]"
		for(var/X in actions)
			var/datum/action/A = X
			A.UpdateButtonIcon()
	else
		icon_state = "cyborg_upgrade5"

/obj/item/borg/upgrade/selfrepair/proc/deactivate()
	SSobj.processing -= src
	on = FALSE
	update_icon()

/obj/item/borg/upgrade/selfrepair/process()
	if(!repair_tick)
		repair_tick = 1
		return

	if(cyborg && (cyborg.stat != DEAD) && on)
		if(cyborg.cell.charge < powercost * 2)
			cyborg << "Self-repair module deactivated. Please recharge."
			deactivate()
			return

		if(cyborg.health < cyborg.maxHealth)
			if(cyborg.health < 0)
				repair_amount = -2.5
				powercost = 30
			else
				repair_amount = -1
				powercost = 10
			cyborg.adjustBruteLoss(repair_amount)
			cyborg.adjustFireLoss(repair_amount)
			cyborg.updatehealth()
			cyborg.cell.use(powercost)
		else
			cyborg.cell.use(5)
		repair_tick = 0

		if((world.time - 2000) > msg_cooldown )
			var/msgmode = "standby"
			if(cyborg.health < 0)
				msgmode = "critical"
			else if(cyborg.health < cyborg.maxHealth)
				msgmode = "normal"
			cyborg << "Self-repair is active in [msgmode] mode."
			msg_cooldown = world.time
	else
		deactivate()


code:
/obj/item/target
	name = "shooting target"
	desc = "A shooting target."
	icon = 'icons/obj/objects.dmi'
	icon_state = "target_h"
	density = 0
	var/hp = 1800
	var/obj/structure/target_stake/pinnedLoc

/obj/item/target/Destroy()
	removeOverlays()
	if(pinnedLoc)
		pinnedLoc.nullPinnedTarget()
	return ..()

/obj/item/target/proc/nullPinnedLoc()
	pinnedLoc = null
	density = 0

/obj/item/target/proc/removeOverlays()
	overlays.Cut()

/obj/item/target/Move()
	..()
	if(pinnedLoc)
		pinnedLoc.loc = loc

/obj/item/target/attackby(obj/item/W, mob/user, params)
	if(istype(W, /obj/item/weapon/weldingtool))
		var/obj/item/weapon/weldingtool/WT = W
		if(WT.remove_fuel(0, user))
			removeOverlays()
			usr << "You slice off [src]'s uneven chunks of aluminium and scorch marks."

/obj/item/target/attack_hand(mob/user)
	if(pinnedLoc)
		pinnedLoc.removeTarget(user)
	..()

/obj/item/target/syndicate
	icon_state = "target_s"
	desc = "A shooting target that looks like a syndicate scum."
	hp = 2600

/obj/item/target/alien
	icon_state = "target_q"
	desc = "A shooting target that looks like a xenomorphic alien."
	hp = 2350

/obj/item/target/clown
	icon_state = "target_c"
	desc = "A shooting target that looks like a useless clown."
	hp = 2000

#define DECALTYPE_SCORCH 1
#define DECALTYPE_BULLET 2

/obj/item/target/clown/bullet_act(obj/item/projectile/P)
	..()
	playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)

/obj/item/target/bullet_act(obj/item/projectile/P)
	var/p_x = P.p_x + pick(0,0,0,0,0,-1,1) // really ugly way of coding "sometimes offset P.p_x!"
	var/p_y = P.p_y + pick(0,0,0,0,0,-1,1)
	var/decaltype = DECALTYPE_SCORCH
	if(istype(/obj/item/projectile/bullet, P))
		decaltype = DECALTYPE_BULLET
	var/icon/C = icon(icon,icon_state)
	if(C.GetPixel(p_x, p_y) && P.original == src && overlays.len <= 35) // if the located pixel isn't blank (null)
		hp -= P.damage
		if(hp <= 0)
			visible_message("[src] breaks into tiny pieces and collapses!")
			qdel(src)
		var/image/I = image("icon"='icons/effects/effects.dmi', "icon_state"="scorch", "layer"=OBJ_LAYER+0.5)
		I.pixel_x = p_x - 1 //offset correction
		I.pixel_y = p_y - 1
		if(decaltype == DECALTYPE_SCORCH)
			I.dir = pick(NORTH,SOUTH,EAST,WEST)// random scorch design
			if(P.damage >= 20 || istype(P, /obj/item/projectile/beam/practice))
				I.dir = pick(NORTH,SOUTH,EAST,WEST)
			else
				I.icon_state = "light_scorch"
		else
			I.icon_state = "dent"
		overlays += I
		return
	return -1

#undef DECALTYPE_SCORCH
#undef DECALTYPE_BULLET


code:
/obj/item/stack/spacecash
	name = "space cash"
	desc = "It's worth 1 credit."
	singular_name = "bill"
	icon = 'icons/obj/economy.dmi'
	icon_state = "spacecash"
	amount = 1
	max_amount = 20
	throwforce = 0
	throw_speed = 2
	throw_range = 2
	w_class = 1
	burn_state = FLAMMABLE

/obj/item/stack/spacecash/c10
	icon_state = "spacecash10"
	desc = "It's worth 10 credits."

/obj/item/stack/spacecash/c20
	icon_state = "spacecash20"
	desc = "It's worth 20 credits."

/obj/item/stack/spacecash/c50
	icon_state = "spacecash50"
	desc = "It's worth 50 credits."

/obj/item/stack/spacecash/c100
	icon_state = "spacecash100"
	desc = "It's worth 100 credits."

/obj/item/stack/spacecash/c200
	icon_state = "spacecash200"
	desc = "It's worth 200 credits."

/obj/item/stack/spacecash/c500
	icon_state = "spacecash500"
	desc = "It's worth 500 credits."

/obj/item/stack/spacecash/c1000
	icon_state = "spacecash1000"
	desc = "It's worth 1000 credits."


code:
/obj/item/stack/medical
	name = "medical pack"
	singular_name = "medical pack"
	icon = 'icons/obj/items.dmi'
	amount = 6
	max_amount = 6
	w_class = 1
	throw_speed = 3
	throw_range = 7
	burn_state = FLAMMABLE
	burntime = 5
	var/heal_brute = 0
	var/heal_burn = 0
	var/stop_bleeding = 0
	var/self_delay = 50

/obj/item/stack/medical/attack(mob/living/M, mob/user)

	if(M.stat == 2)
		var/t_him = "it"
		if(M.gender == MALE)
			t_him = "him"
		else if(M.gender == FEMALE)
			t_him = "her"
		user << "\The [M] is dead, you cannot help [t_him]!"
		return

	if(!istype(M, /mob/living/carbon) && !istype(M, /mob/living/simple_animal))
		user << "You don't know how to apply \the [src] to [M]!"
		return 1

	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(stop_bleeding)
			if(H.bleedsuppress)
				user << "[H]'s bleeding is already bandaged!"
				return
			else if(!H.blood_max)
				user << "[H] isn't bleeding!"
				return

	if(isliving(M))
		if(!M.can_inject(user, 1))
			return

	if(user)
		if (M != user)
			if (istype(M, /mob/living/simple_animal))
				var/mob/living/simple_animal/critter = M
				if (!(critter.healable))
					user << " You cannot use [src] on [M]!"
					return
				else if (critter.health == critter.maxHealth)
					user << " [M] is at full health."
					return
				else if(src.heal_brute < 1)
					user << " [src] won't help [M] at all."
					return
			user.visible_message("[user] applies [src] on [M].", "You apply [src] on [M].")
		else
			var/t_himself = "itself"
			if(user.gender == MALE)
				t_himself = "himself"
			else if(user.gender == FEMALE)
				t_himself = "herself"
			user.visible_message("[user] starts to apply [src] on [t_himself]...", "You begin applying [src] on yourself...")
			if(!do_mob(user, M, self_delay))
				return
			user.visible_message("[user] applies [src] on [t_himself].", "You apply [src] on yourself.")

	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected))
		if(stop_bleeding)
			if(!H.bleedsuppress) //so you can't stack bleed suppression
				H.suppress_bloodloss(stop_bleeding)
		if(affecting.status == ORGAN_ORGANIC) //Limb must be organic to be healed - RR
			if(affecting.heal_damage(src.heal_brute, src.heal_burn, 0))
				H.update_damage_overlays(0)

			M.updatehealth()
		else
			user << "Medicine won't work on a robotic limb!"
	else
		M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2))

	use(1)

/obj/item/stack/medical/bruise_pack
	name = "bruise pack"
	singular_name = "bruise pack"
	desc = "A theraputic gel pack and bandages designed to treat blunt-force trauma."
	icon_state = "brutepack"
	heal_brute = 40
	origin_tech = "biotech=1"
	self_delay = 20

/obj/item/stack/medical/gauze
	name = "medical gauze"
	desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, but does not heal wounds."
	gender = PLURAL
	singular_name = "medical gauze"
	icon_state = "gauze"
	stop_bleeding = 1800
	self_delay = 20

/obj/item/stack/medical/gauze/improvised
	name = "improvised gauze"
	singular_name = "improvised gauze"
	desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
	stop_bleeding = 900

/obj/item/stack/medical/gauze/cyborg/
	materials = list()
	is_cyborg = 1
	cost = 250

/obj/item/stack/medical/ointment
	name = "ointment"
	desc = "Used to treat those nasty burn wounds."
	gender = PLURAL
	singular_name = "ointment"
	icon_state = "ointment"
	heal_burn = 40
	origin_tech = "biotech=1"
	self_delay = 20


code:
var/global/list/datum/stack_recipe/rod_recipes = list ( \
	new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("scooter frame", /obj/item/scooter_frame, 10, time = 25, one_per_turf = 0), \
	)

/obj/item/stack/rods
	name = "metal rod"
	desc = "Some rods. Can be used for building, or something."
	singular_name = "metal rod"
	icon_state = "rods"
	item_state = "rods"
	flags = CONDUCT
	w_class = 3
	force = 9
	throwforce = 10
	throw_speed = 3
	throw_range = 7
	materials = list(MAT_METAL=1000)
	max_amount = 50
	attack_verb = list("hit", "bludgeoned", "whacked")
	hitsound = 'sound/weapons/grenadelaunch.ogg'

/obj/item/stack/rods/New(var/loc, var/amount=null)
	..()

	recipes = rod_recipes
	update_icon()

/obj/item/stack/rods/update_icon()
	var/amount = get_amount()
	if((amount <= 5) && (amount > 0))
		icon_state = "rods-[amount]"
	else
		icon_state = "rods"

/obj/item/stack/rods/attackby(obj/item/W, mob/user, params)
	if (istype(W, /obj/item/weapon/weldingtool))
		var/obj/item/weapon/weldingtool/WT = W

		if(get_amount() < 2)
			user << "You need at least two rods to do this!"
			return

		if(WT.remove_fuel(0,user))
			var/obj/item/stack/sheet/metal/new_item = new(usr.loc)
			user.visible_message("[user.name] shaped [src] into metal with the welding tool.", \
						 "You shape [src] into metal with the welding tool.", \
						 "You hear welding.")
			var/obj/item/stack/rods/R = src
			src = null
			var/replace = (user.get_inactive_hand()==R)
			R.use(2)
			if (!R && replace)
				user.put_in_hands(new_item)
		return

	if(istype(W,/obj/item/weapon/reagent_containers/food/snacks))
		var/obj/item/weapon/reagent_containers/food/snacks/S = W
		if(amount != 1)
			user << "You must use a single rod!"
		else if(S.w_class > 2)
			user << "The ingredient is too big for [src]!"
		else
			var/obj/item/weapon/reagent_containers/food/snacks/customizable/A = new/obj/item/weapon/reagent_containers/food/snacks/customizable/kebab(get_turf(src))
			A.initialize_custom_food(src, S, user)
		return
	..()

/obj/item/stack/rods/cyborg/
	materials = list()
	is_cyborg = 1
	cost = 250

/obj/item/stack/rods/cyborg/update_icon()
	return


code:
/* Glass stack types
 * Contains:
 *		Glass sheets
 *		Reinforced glass sheets
 *		Glass shards - TODO: Move this into code/game/object/item/weapons
 */

/*
 * Glass sheets
 */
/obj/item/stack/sheet/glass
	name = "glass"
	desc = "HOLY SHEET! That is a lot of glass."
	singular_name = "glass sheet"
	icon_state = "sheet-glass"
	materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
	origin_tech = "materials=1"

/obj/item/stack/sheet/glass/cyborg
	materials = list()
	is_cyborg = 1
	cost = 500

/obj/item/stack/sheet/glass/fifty
	amount = 50

/obj/item/stack/sheet/glass/attack_self(mob/user)
	construct_window(user)

/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params)
	..()
	add_fingerprint(user)
	if(istype(W, /obj/item/stack/cable_coil))
		var/obj/item/stack/cable_coil/CC = W
		if (get_amount() < 1 || CC.get_amount() < 5)
			user << "You need five lengths of coil and one sheet of glass to make wired glass!"
			return
		CC.use(5)
		use(1)
		user << "You attach wire to the [name]."
		var/obj/item/stack/light_w/new_tile = new(user.loc)
		new_tile.add_fingerprint(user)
	else if(istype(W, /obj/item/stack/rods))
		var/obj/item/stack/rods/V = W
		if (V.get_amount() >= 1 && src.get_amount() >= 1)
			var/obj/item/stack/sheet/rglass/RG = new (user.loc)
			RG.add_fingerprint(user)
			var/obj/item/stack/sheet/glass/G = src
			src = null
			var/replace = (user.get_inactive_hand()==G)
			V.use(1)
			G.use(1)
			if (!G && replace)
				user.put_in_hands(RG)
		else
			user << "You need one rod and one sheet of glass to make reinforced glass!"
			return
	else
		return ..()

/obj/item/stack/sheet/glass/proc/construct_window(mob/user)
	if(!user || !src)
		return 0
	if(!istype(user.loc,/turf))
		return 0
	if(!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		return 0
	if(zero_amount())
		return 0
	var/title = "Sheet-Glass"
	title += " ([src.get_amount()] sheet\s left)"
	switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null))
		if("One Direction")
			if(!src)
				return 1
			if(src.loc != user)
				return 1

			var/list/directions = new/list(cardinal)
			var/i = 0
			for (var/obj/structure/window/win in user.loc)
				i++
				if(i >= 4)
					user << "There are too many windows in this location."
					return 1
				directions-=win.dir
				if(!(win.ini_dir in cardinal))
					user << "Can't let you do that."
					return 1

			//Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
			var/dir_to_set = 2
			for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
				var/found = 0
				for(var/obj/structure/window/WT in user.loc)
					if(WT.dir == direction)
						found = 1
				if(!found)
					dir_to_set = direction
					break

			var/obj/structure/window/W
			W = new /obj/structure/window( user.loc, 0 )
			W.dir = dir_to_set
			W.ini_dir = W.dir
			W.anchored = 0
			W.air_update_turf(1)
			src.use(1)
			W.add_fingerprint(user)
		if("Full Window")
			if(!src)
				return 1
			if(src.loc != user)
				return 1
			if(src.get_amount() < 2)
				user << "You need more glass to do that!"
				return 1
			if(locate(/obj/structure/window) in user.loc)
				user << "There is a window in the way!"
				return 1
			var/obj/structure/window/W
			W = new /obj/structure/window/fulltile( user.loc, 0 )
			W.anchored = 0
			W.air_update_turf(1)
			W.add_fingerprint(user)
			src.use(2)
	return 0

/*
 * Reinforced glass sheets
 */
/obj/item/stack/sheet/rglass
	name = "reinforced glass"
	desc = "Glass which seems to have rods or something stuck in them."
	singular_name = "reinforced glass sheet"
	icon_state = "sheet-rglass"
	materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
	origin_tech = "materials=2"

/obj/item/stack/sheet/rglass/cyborg
	materials = list()
	var/datum/robot_energy_storage/metsource
	var/datum/robot_energy_storage/glasource
	var/metcost = 250
	var/glacost = 500

/obj/item/stack/sheet/rglass/cyborg/get_amount()
	return min(round(metsource.energy / metcost), round(glasource.energy / glacost))

/obj/item/stack/sheet/rglass/cyborg/use(amount) // Requires special checks, because it uses two storages
	metsource.use_charge(amount * metcost)
	glasource.use_charge(amount * glacost)
	return

/obj/item/stack/sheet/rglass/cyborg/add(amount)
	metsource.add_charge(amount * metcost)
	glasource.add_charge(amount * glacost)
	return

/obj/item/stack/sheet/rglass/attack_self(mob/user)
	construct_window(user)

/obj/item/stack/sheet/rglass/proc/construct_window(mob/user)
	if(!user || !src)
		return 0
	if(!istype(user.loc,/turf))
		return 0
	if(!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		return 0
	var/title = "Sheet Reinf. Glass"
	title += " ([src.get_amount()] sheet\s left)"
	switch(input(title, "Would you like full tile glass a one direction glass pane or a windoor?") in list("One Direction", "Full Window", "Windoor", "Cancel"))
		if("One Direction")
			if(!src)
				return 1
			if(src.loc != user)
				return 1
			var/list/directions = new/list(cardinal)
			var/i = 0
			for (var/obj/structure/window/win in user.loc)
				i++
				if(i >= 4)
					user << "There are too many windows in this location."
					return 1
				directions-=win.dir
				if(!(win.ini_dir in cardinal))
					user << "Can't let you do that."
					return 1

			//Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
			var/dir_to_set = 2
			for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
				var/found = 0
				for(var/obj/structure/window/WT in user.loc)
					if(WT.dir == direction)
						found = 1
				if(!found)
					dir_to_set = direction
					break

			var/obj/structure/window/W
			W = new /obj/structure/window/reinforced( user.loc, 1 )
			W.state = 0
			W.dir = dir_to_set
			W.ini_dir = W.dir
			W.anchored = 0
			W.add_fingerprint(user)
			src.use(1)

		if("Full Window")
			if(!src)
				return 1
			if(src.loc != user)
				return 1
			if(src.get_amount() < 2)
				user << "You need more glass to do that!"
				return 1
			if(locate(/obj/structure/window) in user.loc)
				user << "There is a window in the way!"
				return 1
			var/obj/structure/window/W
			W = new /obj/structure/window/reinforced/fulltile(user.loc, 1)
			W.state = 0
			W.anchored = 0
			W.add_fingerprint(user)
			src.use(2)

		if("Windoor")
			if(!src || src.loc != user || !isturf(user.loc))
				return 1

			for(var/obj/structure/windoor_assembly/WA in user.loc)
				if(WA.dir == user.dir)
					user << "There is already a windoor assembly in that location!"
					return 1

			for(var/obj/machinery/door/window/W in user.loc)
				if(W.dir == user.dir)
					user << "There is already a windoor in that location!"
					return 1

			if(src.get_amount() < 5)
				user << "You need more glass to do that!"
				return 1

			var/obj/structure/windoor_assembly/WD = new(user.loc)
			WD.state = "01"
			WD.anchored = 0
			WD.add_fingerprint(user)
			src.use(5)
			switch(user.dir)
				if(SOUTH)
					WD.dir = SOUTH
					WD.ini_dir = SOUTH
				if(EAST)
					WD.dir = EAST
					WD.ini_dir = EAST
				if(WEST)
					WD.dir = WEST
					WD.ini_dir = WEST
				else //If the user is facing northeast. northwest, southeast, southwest or north, default to north
					WD.dir = NORTH
					WD.ini_dir = NORTH
		else
			return 1

	return 0

/obj/item/weapon/shard
	name = "shard"
	desc = "A nasty looking shard of glass."
	icon = 'icons/obj/shards.dmi'
	icon_state = "large"
	w_class = 1
	force = 5
	throwforce = 10
	item_state = "shard-glass"
	materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
	attack_verb = list("stabbed", "slashed", "sliced", "cut")
	hitsound = 'sound/weapons/bladeslice.ogg'
	var/cooldown = 0
	sharpness = IS_SHARP

/obj/item/weapon/shard/suicide_act(mob/user)
	user.visible_message(pick("[user] is slitting \his wrists with the shard of glass! It looks like \he's trying to commit suicide.", \
						"[user] is slitting \his throat with the shard of glass! It looks like \he's trying to commit suicide."))
	return (BRUTELOSS)

/obj/item/weapon/shard/New()
	icon_state = pick("large", "medium", "small")
	switch(icon_state)
		if("small")
			pixel_x = rand(-12, 12)
			pixel_y = rand(-12, 12)
		if("medium")
			pixel_x = rand(-8, 8)
			pixel_y = rand(-8, 8)
		if("large")
			pixel_x = rand(-5, 5)
			pixel_y = rand(-5, 5)

/obj/item/weapon/shard/afterattack(atom/A as mob|obj, mob/user, proximity)
	if(!proximity || !(src in user))
		return
	if(isturf(A))
		return
	if(istype(A, /obj/item/weapon/storage))
		return

	if(ishuman(user))
		var/mob/living/carbon/human/H = user
		if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.specflags)) // golems, etc
			H << "[src] cuts into your hand!"
			var/organ = (H.hand ? "l_" : "r_") + "arm"
			var/obj/item/organ/limb/affecting = H.get_organ(organ)
			if(affecting.take_damage(force / 2))
				H.update_damage_overlays(0)
	else if(ismonkey(user))
		var/mob/living/carbon/monkey/M = user
		M << "[src] cuts into your hand!"
		M.adjustBruteLoss(force / 2)

/obj/item/weapon/shard/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/weapon/weldingtool))
		var/obj/item/weapon/weldingtool/WT = I
		if(WT.remove_fuel(0, user))
			var/obj/item/stack/sheet/glass/NG = new (user.loc)
			for(var/obj/item/stack/sheet/glass/G in user.loc)
				if(G == NG)
					continue
				if(G.amount >= G.max_amount)
					continue
				G.attackby(NG, user)
			user << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s."
			qdel(src)
	..()

/obj/item/weapon/shard/Crossed(mob/AM)
	if(istype(AM) && has_gravity(loc))
		playsound(loc, 'sound/effects/glass_step.ogg', 50, 1)
		if(ishuman(AM))
			var/mob/living/carbon/human/H = AM
			if(PIERCEIMMUNE in H.dna.species.specflags)
				return 0
			if(!H.shoes)
				H.apply_damage(5,BRUTE,(pick("l_leg", "r_leg")))
				H.Weaken(3)
				if(cooldown < world.time - 10) //cooldown to avoid message spam.
					H.visible_message("[H] steps in the broken glass!", \
							"You step in the broken glass!")
					cooldown = world.time


code:
/obj/item/stack/sheet/animalhide/human
	name = "human skin"
	desc = "The by-product of human farming."
	singular_name = "human skin piece"
	icon_state = "sheet-hide"
	origin_tech = null

var/global/list/datum/stack_recipe/human_recipes = list( \
	new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/hooded/bloated_human, 5, on_floor = 1), \
	)

/obj/item/stack/sheet/animalhide/human/New(var/loc, var/amount=null)
	recipes = human_recipes
	return ..()

/obj/item/stack/sheet/animalhide/generic
	name = "generic skin"
	desc = "A piece of generic skin."
	singular_name = "generic skin piece"
	icon_state = "sheet-hide"
	origin_tech = null

/obj/item/stack/sheet/animalhide/corgi
	name = "corgi hide"
	desc = "The by-product of corgi farming."
	singular_name = "corgi hide piece"
	icon_state = "sheet-corgi"
	origin_tech = null

var/global/list/datum/stack_recipe/corgi_recipes = list ( \
	new/datum/stack_recipe("corgi costume", /obj/item/clothing/suit/hooded/ian_costume, 3, on_floor = 1), \
	)

/obj/item/stack/sheet/animalhide/corgi/New(var/loc, var/amount=null)
	recipes = corgi_recipes
	return ..()

/obj/item/stack/sheet/animalhide/cat
	name = "cat hide"
	desc = "The by-product of cat farming."
	singular_name = "cat hide piece"
	icon_state = "sheet-cat"
	origin_tech = null

/obj/item/stack/sheet/animalhide/monkey
	name = "monkey hide"
	desc = "The by-product of monkey farming."
	singular_name = "monkey hide piece"
	icon_state = "sheet-monkey"
	origin_tech = null

var/global/list/datum/stack_recipe/monkey_recipes = list ( \
	new/datum/stack_recipe("monkey mask", /obj/item/clothing/mask/gas/monkeymask, 1, on_floor = 1), \
	new/datum/stack_recipe("monkey suit", /obj/item/clothing/suit/monkeysuit, 2, on_floor = 1), \
	)

/obj/item/stack/sheet/animalhide/monkey/New(var/loc, var/amount=null)
	recipes = monkey_recipes
	return ..()

/obj/item/stack/sheet/animalhide/lizard
	name = "lizard skin"
	desc = "Sssssss..."
	singular_name = "lizard skin piece"
	icon_state = "sheet-lizard"
	origin_tech = null

/obj/item/stack/sheet/animalhide/xeno
	name = "alien hide"
	desc = "The skin of a terrible creature."
	singular_name = "alien hide piece"
	icon_state = "sheet-xeno"
	origin_tech = null

var/global/list/datum/stack_recipe/xeno_recipes = list ( \
	new/datum/stack_recipe("alien helmet", /obj/item/clothing/head/xenos, 1, on_floor = 1), \
	new/datum/stack_recipe("alien suit", /obj/item/clothing/suit/xenos, 2, on_floor = 1), \
	)

/obj/item/stack/sheet/animalhide/xeno/New(var/loc, var/amount=null)
	recipes = xeno_recipes
	return ..()

//don't see anywhere else to put these, maybe together they could be used to make the xenos suit?
/obj/item/stack/sheet/xenochitin
	name = "alien chitin"
	desc = "A piece of the hide of a terrible creature."
	singular_name = "alien hide piece"
	icon = 'icons/mob/alien.dmi'
	icon_state = "chitin"
	origin_tech = null

/obj/item/xenos_claw
	name = "alien claw"
	desc = "The claw of a terrible creature."
	icon = 'icons/mob/alien.dmi'
	icon_state = "claw"
	origin_tech = null

/obj/item/weed_extract
	name = "weed extract"
	desc = "A piece of slimy, purplish weed."
	icon = 'icons/mob/alien.dmi'
	icon_state = "weed_extract"
	origin_tech = null

/obj/item/stack/sheet/hairlesshide
	name = "hairless hide"
	desc = "This hide was stripped of it's hair, but still needs tanning."
	singular_name = "hairless hide piece"
	icon_state = "sheet-hairlesshide"
	origin_tech = null

/obj/item/stack/sheet/wetleather
	name = "wet leather"
	desc = "This leather has been cleaned but still needs to be dried."
	singular_name = "wet leather piece"
	icon_state = "sheet-wetleather"
	origin_tech = null
	var/wetness = 30 //Reduced when exposed to high temperautres
	var/drying_threshold_temperature = 500 //Kelvin to start drying

/obj/item/stack/sheet/leather
	name = "leather"
	desc = "The by-product of mob grinding."
	singular_name = "leather piece"
	icon_state = "sheet-leather"
	origin_tech = "materials=2"

//Step one - dehairing.

/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W, mob/user, params)
	if(is_sharp(W))
		playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
		user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]...", "You hear the sound of a knife rubbing against flesh.")
		if(do_after(user,50, target = src))
			user << "You cut the hair from this [src.singular_name]."
			//Try locating an exisitng stack on the tile and add to there if possible
			for(var/obj/item/stack/sheet/hairlesshide/HS in user.loc)
				if(HS.amount < 50)
					HS.amount++
					use(1)
					break
			//If it gets to here it means it did not find a suitable stack on the tile.
			var/obj/item/stack/sheet/hairlesshide/HS = new(user.loc)
			HS.amount = 1
			use(1)
	else
		..()

//Step two - washing..... it's actually in washing machine code.

//Step three - drying
/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
	..()
	if(exposed_temperature >= drying_threshold_temperature)
		wetness--
		if(wetness == 0)
			//Try locating an exisitng stack on the tile and add to there if possible
			for(var/obj/item/stack/sheet/leather/HS in src.loc)
				if(HS.amount < 50)
					HS.amount++
					src.use(1)
					wetness = initial(wetness)
					break
			//If it gets to here it means it did not find a suitable stack on the tile.
			var/obj/item/stack/sheet/leather/HS = new(src.loc)
			HS.amount = 1
			wetness = initial(wetness)
			src.use(1)


code:
/obj/item/stack/light_w
	name = "wired glass tile"
	singular_name = "wired glass floor tile"
	desc = "A glass tile, which is wired, somehow."
	icon = 'icons/obj/tiles.dmi'
	icon_state = "glass_wire"
	w_class = 3
	force = 3
	throwforce = 5
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	max_amount = 60

/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params)
	..()
	if(istype(O,/obj/item/weapon/wirecutters))
		var/obj/item/stack/cable_coil/CC = new (user.loc)
		CC.amount = 5
		CC.add_fingerprint(user)
		amount--
		var/obj/item/stack/sheet/glass/G = new (user.loc)
		G.add_fingerprint(user)
		if(amount <= 0)
			user.unEquip(src, 1)
			qdel(src)

	if(istype(O, /obj/item/stack/sheet/metal))
		var/obj/item/stack/sheet/metal/M = O
		if (M.use(1))
			use(1)
			var/obj/item/stack/tile/light/L = new (user.loc)
			user << "You make a light tile."
			L.add_fingerprint(user)
		else
			user << "You need one metal sheet to finish the light tile!"
			return


code:
/*
Mineral Sheets
	Contains:
		- Sandstone
		- Sandbags
		- Diamond
		- Snow
		- Uranium
		- Plasma
		- Gold
		- Silver
		- Clown
	Others:
		- Adamantine
		- Mythril
		- Enriched Uranium
*/

/obj/item/stack/sheet/mineral
	icon = 'icons/obj/mining.dmi'

/*
 * Sandstone
 */

var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
	new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
/*	new/datum/stack_recipe("sandstone wall", ???), \
		new/datum/stack_recipe("sandstone floor", ???),\ */
	)

/obj/item/stack/sheet/mineral/sandstone
	name = "sandstone brick"
	desc = "This appears to be a combination of both sand and stone."
	singular_name = "sandstone brick"
	icon_state = "sheet-sandstone"
	throw_speed = 3
	throw_range = 5
	origin_tech = "materials=1"
	materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
	sheettype = "sandstone"

/obj/item/stack/sheet/mineral/sandstone/New(var/loc, var/amount=null)
	recipes = sandstone_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/obj/item/stack/sheet/mineral/sandstone/thirty
	amount = 30

/*
 * Sandbags(
 */

/obj/item/stack/sheet/mineral/sandbags
	name = "sandbags"
	icon = 'icons/obj/items.dmi'
	icon_state = "sandbag"
	singular_name = "sandbag"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=2"

var/global/list/datum/stack_recipe/sandbag_recipes = list ( \
	new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/sandbags/New(var/loc, var/amount=null)
	recipes = sandbag_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Diamond
 */
/obj/item/stack/sheet/mineral/diamond
	name = "diamond"
	icon_state = "sheet-diamond"
	singular_name = "diamond"
	force = 5
	throwforce = 5
	w_class = 3
	throw_range = 3
	origin_tech = "materials=6"
	sheettype = "diamond"
	materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/diamond_recipes = list ( \
	new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20),  \
	new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/diamond/New(var/loc, var/amount=null)
	recipes = diamond_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Uranium
 */
/obj/item/stack/sheet/mineral/uranium
	name = "uranium"
	icon_state = "sheet-uranium"
	singular_name = "uranium sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=5"
	sheettype = "uranium"
	materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/uranium_recipes = list ( \
	new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
	new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/uranium/New(var/loc, var/amount=null)
	recipes = uranium_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Plasma
 */
/obj/item/stack/sheet/mineral/plasma
	name = "solid plasma"
	icon_state = "sheet-plasma"
	singular_name = "plasma sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "plasmatech=2;materials=2"
	sheettype = "plasma"
	burn_state = FLAMMABLE
	burntime = 5
	materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/plasma_recipes = list ( \
	new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
	new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/plasma/New(var/loc, var/amount=null)
	recipes = plasma_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/obj/item/stack/sheet/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
		message_admins("Plasma sheets ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
		log_game("Plasma sheets ignited by [key_name(user)] in ([x],[y],[z])")
		fire_act()
	else
		..()

/obj/item/stack/sheet/mineral/plasma/fire_act()
	atmos_spawn_air("plasma=[amount*10];TEMP=1000")
	qdel(src)

/*
 * Gold
 */
/obj/item/stack/sheet/mineral/gold
	name = "gold"
	icon_state = "sheet-gold"
	singular_name = "gold bar"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"
	sheettype = "gold"
	materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/gold_recipes = list ( \
	new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \
	new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/gold/New(var/loc, var/amount=null)
	recipes = gold_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Silver
 */
/obj/item/stack/sheet/mineral/silver
	name = "silver"
	icon_state = "sheet-silver"
	singular_name = "silver bar"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=3"
	sheettype = "silver"
	materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/silver_recipes = list ( \
	new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \
	new/datum/stack_recipe("Med Officer Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/silver/New(var/loc, var/amount=null)
	recipes = silver_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Clown
 */
/obj/item/stack/sheet/mineral/bananium
	name = "bananium"
	icon_state = "sheet-clown"
	singular_name = "bananium sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"
	sheettype = "clown"
	materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)

var/global/list/datum/stack_recipe/clown_recipes = list ( \
	new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
	new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/bananium/New(var/loc, var/amount=null)
	recipes = clown_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/*
 * Snow
 */
/obj/item/stack/sheet/mineral/snow
	name = "snow"
	icon_state = "sheet-snow"
	singular_name = "snow block"
	force = 1
	throwforce = 2
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=1"
	sheettype = "snow"

var/global/list/datum/stack_recipe/snow_recipes = list ( \
	new/datum/stack_recipe("Snow Wall",/turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Snowman", /obj/structure/statue/snow/snowman, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Snowball", /obj/item/toy/snowball, 1), \
	)

/obj/item/stack/sheet/mineral/snow/New(var/loc, var/amount=null)
	recipes = snow_recipes
	pixel_x = rand(0,4)-4
	pixel_y = rand(0,4)-4
	..()

/****************************** Others ****************************/

/*
 * Enriched Uranium
 */
/obj/item/stack/sheet/mineral/enruranium
	name = "enriched uranium"
	icon_state = "sheet-enruranium"
	singular_name = "enriched uranium sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=6"
	materials = list(MAT_URANIUM=3000)

/*
 * Adamantine
 */
/obj/item/stack/sheet/mineral/adamantine
	name = "adamantine"
	icon_state = "sheet-adamantine"
	singular_name = "adamantine sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"

/*
 * Mythril
 */
/obj/item/stack/sheet/mineral/mythril
	name = "mythril"
	icon_state = "sheet-mythril"
	singular_name = "mythril sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"

/*
 * Alien Alloy
 */
/obj/item/stack/sheet/mineral/abductor
	name = "alien alloy"
	icon = 'icons/obj/abductor.dmi'
	icon_state = "sheet-abductor"
	singular_name = "alien alloy sheet"
	force = 5
	throwforce = 5
	w_class = 3
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=6;abductor=1"
	sheettype = "abductor"

var/global/list/datum/stack_recipe/abductor_recipes = list ( \
/*	new/datum/stack_recipe("alien chair", /obj/structure/chair, one_per_turf = 1, on_floor = 1), \ */
	new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = 1, on_floor = 1), \
	null, \
	new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \
/*	null, \
	new/datum/stack_recipe("Abductor Agent Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("Abductor Sciencist Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1)*/
	)

/obj/item/stack/sheet/mineral/abductor/New(var/loc, var/amount=null)
	recipes = abductor_recipes
	..()