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.
	m_amt = 60
	g_amt = 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/datum/wires/taperecorder/wires = null
	var/canprint = 1

/obj/item/device/taperecorder/New()
	wires = new(src)
	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))
		user.drop_item()
		I.loc = src
		mytape = I
		user << "You insert [I] into [src]."
		update_icon()
	else if(istype(I, /obj/item/weapon/screwdriver))
		open_panel = !open_panel
		user << "You [open_panel ? "open" : "close"] the wire panel."
		if(open_panel)
			wires.Interact(user)
	else if(istype(I, /obj/item/weapon/wirecutters) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler))
		wires.Interact(user)

/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/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.stat && user.canmove && !user.restrained())
			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)
	if(mytape && recording)
		mytape.timestamp += mytape.used_capacity
		mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [strip_html_properly(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(!wires.get_record())
		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
			if(!wires.get_record())
				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
	if(!wires.get_play())
		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(!wires.get_play())
			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()
	wires = new(src)
	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
	m_amt = 20
	g_amt = 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/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))
			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.0
	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 as mob, 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", admin=0, object="[src]")

	for(var/mob/living/carbon/human/M in orange(10, user))
		spawn()
			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.0
	throw_speed = 3
	throw_range = 7
	m_amt = 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 as mob, mob/living/user as mob)
	if(!used)
		add_logs(user, M, "irradiated", object="[src.name]")
		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.apply_effect(intensity*10, IRRADIATE)
	else
		user << "The radioactive microlaser is still recharging."

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

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

/obj/item/device/rad_laser/interact(mob/user as mob)
	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

license: mit


code:
/obj/item/device/transfer_valve
	icon = 'icons/obj/assemblies.dmi'
	name = "tank transfer valve"
	icon_state = "valve_1"
	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)
			tank_one = item
			user.drop_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)
			tank_two = item
			user.drop_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/HasProximity(atom/movable/AM as mob|obj)
	if(!attached_device)	return
	attached_device.HasProximity(AM)
	return
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
	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(var/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 = "[attacher.name]([attacher.ckey])"

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

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

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

		var/log_str3 = " Last touched by: [src.fingerprintslast]"

		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:
//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak

/*

A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message.

*/

var/list/world_uplinks = list()

/obj/item/device/uplink
	var/welcome = "Syndicate Uplink Console:"	// Welcoming menu message
	var/uses = 20								// Numbers of crystals
	// List of items not to shove in their hands.
	var/purchase_log = ""
	var/show_description = null
	var/active = 0

	var/uplink_owner = null//text-only
	var/used_TC = 0

/obj/item/device/uplink/New()
	..()
	world_uplinks+=src

/obj/item/device/uplink/Destroy()
	world_uplinks-=src
	..()

//Let's build a menu!
/obj/item/device/uplink/proc/generate_menu()

	var/dat = "[src.welcome]
"
	dat += "Tele-Crystals left: [src.uses]
"
	dat += "
"
	dat += "Request item:
"
	dat += "Each item costs a number of tele-crystals as indicated by the number following their name.

"

	var/list/buyable_items = get_uplink_items()

	// Loop through categories
	var/index = 0
	for(var/category in buyable_items)

		index++
		dat += "[category]
"

		var/i = 0

		// Loop through items in category
		for(var/datum/uplink_item/item in buyable_items[category])
			i++
			var/desc = "[item.desc]"
			var/cost_text = ""
			if(item.cost > 0)
				cost_text = "([item.cost])"
			if(item.cost <= uses)
				dat += "[item.name] [cost_text] "
			else
				dat += "[item.name] [cost_text] "
			if(item.desc)
				if(show_description == item.type)
					dat += "\[-\]
[desc]"
				else
					dat += "\[?\]"
			dat += "
"

		// Break up the categories, if it isn't the last.
		if(buyable_items.len != index)
			dat += "
"

	dat += "
"
	return dat

// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
/obj/item/device/uplink/interact(mob/user as mob)

	var/dat = ""
	dat += src.generate_menu()
	dat += "Lock"
	dat += ""
	user << browse(dat, "window=hidden")
	onclose(user, "hidden")
	return

/obj/item/device/uplink/Topic(href, href_list)
	..()

	if(!active)
		return

	if (href_list["buy_item"])

		var/item = href_list["buy_item"]
		var/list/split = text2list(item, ":") // throw away variable

		if(split.len == 2)
			// Collect category and number
			var/category = split[1]
			var/number = text2num(split[2])

			var/list/buyable_items = get_uplink_items()

			var/list/uplink = buyable_items[category]
			if(uplink && uplink.len >= number)
				var/datum/uplink_item/I = uplink[number]
				if(I)
					I.buy(src, usr)

	else if(href_list["show_desc"])

		var/type = text2path(href_list["show_desc"])
		show_description = type
		interact(usr)

// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
/* How to create an uplink in 3 easy steps!

 1. All obj/item 's have a hidden_uplink var. By default it's null. Give the item one with "new(src)", it must be in it's contents. Feel free to add "uses".

 2. Code in the triggers. Use check_trigger for this, I recommend closing the item's menu with "usr << browse(null, "window=windowname") if it returns true.
 The var/value is the value that will be compared with the var/target. If they are equal it will activate the menu.

 3. If you want the menu to stay until the users locks his uplink, add an active_uplink_check(mob/user as mob) in your interact/attack_hand proc.
 Then check if it's true, if true return. This will stop the normal menu appearing and will instead show the uplink menu.
*/

/obj/item/device/uplink/hidden
	name = "hidden uplink."
	desc = "There is something wrong if you're examining this."

/obj/item/device/uplink/hidden/Topic(href, href_list)
	if(usr.stat || usr.restrained() || usr.paralysis || usr.stunned || usr.weakened)
		return 0		// To stop people using their uplink when they shouldn't be able to
	..()
	if(href_list["lock"])
		toggle()
		usr << browse(null, "window=hidden")
		return 1

// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
/obj/item/device/uplink/hidden/proc/toggle()
	active = !active

// Directly trigger the uplink. Turn on if it isn't already.
/obj/item/device/uplink/hidden/proc/trigger(mob/user as mob)
	if(!active)
		toggle()
	interact(user)

// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset.
// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the
// current item's menu.
/obj/item/device/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target)
	if(value == target)
		trigger(user)
		return 1
	return 0

// I placed this here because of how relevant it is.
// You place this in your uplinkable item to check if an uplink is active or not.
// If it is, it will display the uplink menu and return 1, else it'll return false.
// If it returns true, I recommend closing the item's normal menu with "user << browse(null, "window=name")"
/obj/item/proc/active_uplink_check(mob/user as mob)
	// Activates the uplink if it's active
	if(src.hidden_uplink)
		if(src.hidden_uplink.active)
			src.hidden_uplink.trigger(user)
			return 1
	return 0
//Refund proc for the borg teleporter (later I'll make a general refund proc if there is demand for it)
/obj/item/device/radio/uplink/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	if(istype(W, /obj/item/weapon/antag_spawner/borg_tele))
		var/obj/item/weapon/antag_spawner/borg_tele/S = W
		if(!S.used)
			hidden_uplink.uses += S.TC_cost
			qdel(S)
			user << "Teleporter refunded."
		else
			user << "This teleporter is already used."

// PRESET UPLINKS
// A collection of preset uplinks.
//
// Includes normal radio uplink, multitool uplink,
// implant uplink (not the implant tool) and a preset headset uplink.

/obj/item/device/radio/uplink/New()
	hidden_uplink = new(src)
	icon_state = "radio"

/obj/item/device/radio/uplink/attack_self(mob/user as mob)
	if(hidden_uplink)
		hidden_uplink.trigger(user)

/obj/item/device/multitool/uplink/New()
	hidden_uplink = new(src)

/obj/item/device/multitool/uplink/attack_self(mob/user as mob)
	if(hidden_uplink)
		hidden_uplink.trigger(user)

/obj/item/device/radio/headset/uplink
	traitor_frequency = 1445

/obj/item/device/radio/headset/uplink/New()
	..()
	hidden_uplink = new(src)
	hidden_uplink.uses = 20


code:
//copy pasta of the space piano, don't hurt me -Pete

/obj/item/device/violin
	name = "space violin"
	desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
	icon = 'icons/obj/musician.dmi'
	icon_state = "violin"
	item_state = "violin"
	force = 10
	var/datum/song/handheld/song
	hitsound = "swing_hit"

/obj/item/device/violin/New()
	song = new("violin", src)
	song.instrumentExt = "ogg"

/obj/item/device/violin/Destroy()
	qdel(song)
	song = null
	..()

/obj/item/device/violin/attack_self(mob/user as mob)
	if(!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		return 1
	interact(user)

/obj/item/device/violin/interact(mob/user as mob)
	if(!user)
		return

	if(!isliving(user) || user.stat || user.restrained() || user.lying)
		return

	user.set_machine(src)
	song.interact(user)


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

/obj/item/documents/nanotrasen
	desc = "\"Top Secret\" Nanotrasen documents printed on special copy-protected paper. It is filled with complex diagrams and lists of names, dates and coordinates."
	icon_state = "docs_verified"

/obj/item/documents/syndicate
	desc = "\"Top Secret\" documents printed on special copy-protected paper. It details sensitive Syndicate operational intelligence."

/obj/item/documents/syndicate/red
	name = "'Red' secret documents"
	desc = "\"Top Secret\" documents printed on special copy-protected paper. It details sensitive Syndicate operational intelligence. These documents are marked \"Red\"."
	icon_state = "docs_red"

/obj/item/documents/syndicate/blue
	name = "'Blue' secret documents"
	desc = "\"Top Secret\" documents printed on special copy-protected paper. It details sensitive Syndicate operational intelligence. These documents are marked \"Blue\"."
	icon_state = "docs_blue"


code:
#define MAX_TAPE_RANGE 3
//The max length of a line of hazard tape by tile range

//Define all tape types in hazardtape.dm
/obj/item/tapeproj
	icon = 'icons/obj/holotape.dmi'
	icon_state = "rollstart"
	w_class = 2.0
	var/turf/start
	var/turf/end
	var/tape_type = /obj/item/holotape
	var/icon_base
	var/charging = 0

/obj/item/holotape
	icon = 'icons/obj/holotape.dmi'
	anchored = 1
	density = 1
	var/icon_base
	var/health = 10

/obj/item/tapeproj/security
	name = "security holotape projector"
	desc = "A security hard-light holotape projector used to create holotape. It can be placed in segments along hallways or on airlocks to signify crime scenes."
	icon_state = "security_start"
	tape_type = /obj/item/holotape/security
	icon_base = "security"

/obj/item/holotape/security
	name = "security holotape"
	desc = "A length of security hard-light holotape. It reads: SECURITY LINE | DO NOT CROSS."
	icon_base = "security"

/obj/item/tapeproj/engineering
	name = "engineering holotape projector"
	desc = "An engineering hard-light holotape projector used to create holotape. It can be placed in segments along hallways or on airlocks to show hazardous areas."
	icon_state = "engineering_start"
	tape_type = /obj/item/holotape/engineering
	icon_base = "engineering"

/obj/item/holotape/engineering
	name = "engineering holotape"
	desc = "A length of engineering hard-light holotape. It reads: HAZARD AHEAD // DO NOT CROSS."
	icon_base = "engineering"

/obj/item/tapeproj/dropped()
	reset()

/obj/item/tapeproj/equipped()
	reset()

/obj/item/tapeproj/proc/reset()
	if(icon_state == "[icon_base]_stop")
		icon_state = "[icon_base]_start"
		start = null
		return

/obj/item/tapeproj/attack_self(var/mob/user)
	if(charging)
		usr << "[src] is recharging!"
		return
	if(icon_state == "[icon_base]_start")
		start = get_turf(src)
		usr << "You project the start of the [icon_base] holotape."
		icon_state = "[icon_base]_stop"
	else
		icon_state = "[icon_base]_start"
		end = get_turf(src)
		if(start.y != end.y && start.x != end.x || start.z != end.z)
			usr << "[src] can only be projected horizontally or vertically."
			return
		if(get_dist(start,end) >= MAX_TAPE_RANGE)
			usr << "Your holotape segment is too long! It must be [MAX_TAPE_RANGE] tiles long or shorter!"
			return

		var/turf/cur = start
		var/dir
		if(start.x == end.x)
			var/d = end.y-start.y
			if(d) d = d/abs(d)
			end = get_turf(locate(end.x,end.y+d,end.z))
			dir = "v"
		else
			var/d = end.x-start.x
			if(d) d = d/abs(d)
			end = get_turf(locate(end.x+d,end.y,end.z))
			dir = "h"

		var/can_place = 1
		while (cur!=end && can_place)
			if(cur.density == 1)
				can_place = 0
			else if(istype(cur, /turf/space))
				can_place = 0
			else
				for(var/obj/O in cur)
					if(!istype(O, /obj/item/holotape) && O.density)
						can_place = 0
						break
			cur = get_step_towards(cur,end)
		if(!can_place)
			usr << "You can't project the [icon_base] holotape through that!"
			return

		cur = start
		var/tapetest = 0
		while (cur!=end)
			for(var/obj/item/holotape/Ptest in cur)
				if(Ptest.icon_state == "[Ptest.icon_base]_[dir]")
					tapetest = 1
			if(tapetest != 1)
				var/obj/item/holotape/P = new tape_type(cur)
				P.icon_state = "[P.icon_base]_[dir]"
			cur = get_step_towards(cur,end)

		usr << "You finish project the legnth of [icon_base] holotape."
		user.visible_message("[user] finishes projecting the length of [icon_base] holotape.")

		charging = 1
		spawn(40)
			charging = 0

/obj/item/tapeproj/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
	if(charging)
		return

	if(proximity_flag == 0) // not adjacent
		return

	if(istype(target, /obj/machinery/door/airlock) || istype(target, /obj/machinery/door/firedoor) || istype(target, /obj/structure/window))
		var/turf = get_turf(target)

		if(locate(tape_type) in turf) //Don't you dare stack tape
			return

		if(istype(target, /obj/structure/window))
			var/obj/structure/window/W = target
			if(!(W.dir == 5) || !(W.fulltile == 1))
				return

		user << "You start projecting the [icon_base] holotape onto [target]."

		if(!do_mob(user, target, 30))
			return

		var/atom/tape = new tape_type(turf)
		tape.icon_state = "[icon_base]_door"
		tape.layer = 3.2

		user << "You project the [icon_base] holotape onto [target]."

		charging = 1
		spawn(40)
			charging = 0

/obj/item/holotape/Bumped(var/mob/M)
	if(!istype(M))
		return
	if(iscarbon(M))
		var/mob/living/carbon/C = M
		if(C.m_intent == "walk")
			var/turf/T = get_turf(src)
			C.loc = T

	if(M.has_unlimited_silicon_privilege)
		var/turf/T = get_turf(src)
		M.loc = T

/obj/item/holotape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
	if(!density) return 1
	if(air_group || (height==0)) return 1

	if((mover.flags & PASSGLASS || istype(mover, /obj/effect/meteor) || mover.throwing == 1) )
		return 1
	else
		return 0

/obj/item/holotape/attack_hand(mob/living/user)
	user.changeNext_move(CLICK_CD_MELEE)
	user.do_attack_animation(src)
	playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
	user.visible_message("[user] hits [src].", \
						 "You hit [src]." )

	health -= rand(1,2)
	healthcheck()

/obj/item/holotape/proc/healthcheck()
	if(health <= 0)
		breaktape()

/obj/item/holotape/ex_act(severity, target)
	breaktape()

/obj/item/holotape/blob_act()
	breaktape()

/obj/item/holotape/attack_paw(mob/living/user)
	attack_hand(user)

/obj/item/holotape/bullet_act(var/obj/item/projectile/Proj)
	if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
		health -= Proj.damage
	..()
	if(health <= 0)
		breaktape()
	return

/obj/item/holotape/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	user.changeNext_move(CLICK_CD_MELEE)
	add_fingerprint(user)
	health -= W.force * 0.3

	healthcheck()
	..()
	return

/obj/item/holotape/hitby(AM as mob|obj)
	..()
	visible_message("[src] was hit by [AM].")
	var/tforce = 0
	if(ismob(AM))
		tforce = 5
	else if(isobj(AM))
		var/obj/item/I = AM
		tforce = max(0, I.throwforce * 0.5)
	playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
	health = max(0, health - tforce)
	healthcheck()

/obj/item/holotape/proc/breaktape()
	var/dir[2]
	var/icon_dir = src.icon_state
	if(icon_dir == "[src.icon_base]_h")
		dir[1] = EAST
		dir[2] = WEST
	if(icon_dir == "[src.icon_base]_v")
		dir[1] = NORTH
		dir[2] = SOUTH

	for(var/i=1;i<3;i++)
		var/N = 0
		var/turf/cur = get_step(src,dir[i])
		while(N != 1)
			N = 1
			for (var/obj/item/holotape/P in cur)
				if(P.icon_state == icon_dir)
					N = 0
					del(P)
			cur = get_step(cur,dir[i])

	del(src)
	return

#undef MAX_TAPE_RANGE


code:
/obj/item/latexballon
	name = "latex glove"
	desc = "" //todo
	icon_state = "latexballon"
	item_state = "lgloves"
	force = 0
	throwforce = 0
	w_class = 1.0
	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 as mob)
	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 as obj, mob/user as mob, params)
	if(istype(W, /obj/item/weapon/tank))
		var/obj/item/weapon/tank/T = W
		blow(T, user)
		return
	if (is_sharp(W) || is_hot(W) || is_pointed(W))
		burst()


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

/**********************************************************************
						Cyborg Spec Items
***********************************************************************/
//Might want to move this into several files later but for now it works here
/obj/item/borg/stun
	name = "electrified arm"
	icon = 'icons/mob/robot_items.dmi'
	icon_state = "elecarm"

/obj/item/borg/stun/attack(mob/M as mob, mob/living/silicon/robot/user as mob)

	user.cell.charge -= 30

	M.Weaken(5)
	if (M.stuttering < 5)
		M.stuttering = 5
	M.Stun(5)

	for(var/mob/O in viewers(M, null))
		if (O.client)
			O.show_message("[user] has prodded [M] with an electrically-charged arm!", 1,
							 " You hear someone fall", 2)
	add_logs(user, M, "stunned", object="[src.name]", addition="(INTENT: [uppertext(user.a_intent)])")

/obj/item/borg/overdrive
	name = "overdrive"
	icon = 'icons/obj/decals.dmi'
	icon_state = "shock"

/**********************************************************************
						HUD/SIGHT things
***********************************************************************/
/obj/item/borg/sight
	icon = 'icons/obj/decals.dmi'
	icon_state = "securearea"
	var/sight_mode = null

/obj/item/borg/sight/xray
	name = "\proper x-ray Vision"
	sight_mode = BORGXRAY

/obj/item/borg/sight/thermal
	name = "\proper thermal vision"
	sight_mode = BORGTHERM
	icon = 'icons/mob/robot_items.dmi'
	icon_state = "thermal"

/obj/item/borg/sight/meson
	name = "\proper meson vision"
	sight_mode = BORGMESON
	icon = 'icons/mob/robot_items.dmi'
	icon_state = "meson"

/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 = 'icons/mob/robot_items.dmi'
	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 = 'icons/mob/robot_items.dmi'
	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/wires = 0.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/flash/handheld/flash1 = null
	var/obj/item/device/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 as obj, mob/user as mob, 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 armed 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
		user.drop_item()
		W.loc = src
		src.l_leg = W
		src.updateicon()

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

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

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

	if(istype(W, /obj/item/robot_parts/chest))
		if(src.chest)	return
		if(W:wires && W:cell)
			user.drop_item()
			W.loc = src
			src.chest = W
			src.updateicon()
		else if(!W:wires)
			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)
			user.drop_item()
			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))
		if(user && ismommi(user))
			var/mob/living/silicon/robot/mommi/R = user
			if(R.keeper)
				user << "Your laws forbid you from doing this"
				return

		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)
				user << "Sticking a dead brain into the frame would sort of defeat the purpose!"
				return

			if((BM.mind in ticker.mode.head_revolutionaries) || (BM.mind in ticker.mode.A_bosses) || (BM.mind in ticker.mode.B_bosses))
				user << "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the MMI!"
				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

			user.drop_item()

			O.invisibility = 0
			//Transfer debug settings to new mob
			O.custom_name = created_name
			O.updatename("Default")
			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)
				O.lawupdate = 0
				O.make_laws()
				if(ticker.mode.config_tag == "malfunction") //Don't let humans get a cyborg on their side during malf, for balance reasons.
					O.set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*�&110010")

			M.brainmob.mind.transfer_to(O)

			if(O.mind && O.mind.special_role)
				O.mind.store_memory("As a cyborg, any objectives listed here are null and void, and will be marked as failed. They are simply here for memory purposes.")

			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.
			O.updatename()
			O.mmi = W

			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 as obj, mob/user as mob, params)
	..()
	if(istype(W, /obj/item/weapon/stock_parts/cell))
		if(src.cell)
			user << "You have already inserted a cell!"
			return
		else
			user.drop_item()
			W.loc = src
			src.cell = W
			user << "You insert the cell!"
	if(istype(W, /obj/item/stack/cable_coil))
		if(src.wires)
			user << "You have already inserted wire."
			return
		var/obj/item/stack/cable_coil/coil = W
		if (coil.use(1))
			src.wires = 1.0
			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 as obj, mob/user as mob, params)
	..()
	if(istype(W, /obj/item/device/flash/handheld))
		var/obj/item/device/flash/handheld/F = W
		if(src.flash1 && src.flash2)
			user << "You have already inserted the eyes!"
			return
		else if(F.broken)
			user << "You can't use a broken flash!"
			return
		else
			user.drop_item()
			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"
	var/locked = 0
	var/require_module = 0
	var/installed = 0

/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R)
	if(R.stat == DEAD)
		usr << "[src] will not function on a deceased cyborg."
		return 1
	return 0

/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(var/mob/living/silicon/robot/R)
	if(..()) return 0
	R.uneq_all()
	R.hands.icon_state = "nomod"
	R.icon_state = "robot"
	qdel(R.module)
	R.module = null
	R.modtype = "robot"
	R.updatename("Default")
	R.status_flags |= CANPUSH
	R.designation = "Default"
	R.notify_ai(2)
	R.update_icons()

	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 as mob)
	heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)

/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R)
	if(..()) return 0
	R.notify_ai(3, R.name, heldname)
	R.name = heldname
	R.real_name = heldname
	R.camera.c_tag = heldname
	R.custom_name = heldname //Required or else if the cyborg's module changes, their name is lost.

	return 1

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

/obj/item/borg/upgrade/restart/action(var/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.stat = CONSCIOUS
	dead_mob_list -= R //please never forget this ever kthx
	living_mob_list += R
	R.notify_ai(1)

	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

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

	if(R.speed == -1)
		return 0

	R.speed--
	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

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

	if(!istype(R.module, /obj/item/weapon/robot_module/security))
		R << "Upgrade mounting error!  No suitable hardpoint detected!"
		usr << "There's no mounting point for the module!"
		return 0

	var/obj/item/weapon/gun/energy/disabler/cyborg/T = locate() in R.module
	if(!T)
		T = locate() in R.module.contents
	if(!T)
		T = locate() in R.module.modules
	if(!T)
		usr << "This cyborg has had its disabler removed!"
		return 0

	if(T.recharge_time <= 2)
		R << "Maximum cooling achieved for this hardpoint!"
		usr << "There's no room for another cooling unit!"
		return 0

	else
		T.recharge_time = max(2 , T.recharge_time - 4)

	return 1

/obj/item/borg/upgrade/jetpack
	name = "mining cyborg jetpack"
	desc = "A carbon dioxide jetpack suitable for low-gravity mining operations."
	icon_state = "cyborg_upgrade3"
	require_module = 1

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

	if(!istype(R.module, /obj/item/weapon/robot_module/miner))
		R << "Upgrade mounting error!  No suitable hardpoint detected!"
		usr << "There's no mounting point for the module!"
		return 0
	else
		R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide(R.module)
		for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules)
			R.internals = src
		R.jetpackoverlay = 1
		R.module.rebuild()
		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

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

	if(!istype(R.module, /obj/item/weapon/robot_module/miner))
		R << "Upgrade mounting error!  No suitable hardpoint detected!"
		usr << "There's no mounting point for the module!"
		return 0
	else
		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/diamonddrill(src)
		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

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

	if(R.emagged == 1)
		return 0

	R.SetEmagged(1)
	return 1


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()
	..()

/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

#define DECALTYPE_SCORCH 1
#define DECALTYPE_BULLET 2

/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/medical
	name = "medical pack"
	singular_name = "medical pack"
	icon = 'icons/obj/items.dmi'
	amount = 5
	max_amount = 5
	w_class = 1
	throw_speed = 3
	throw_range = 7
	var/heal_brute = 0
	var/heal_burn = 0
	var/stop_bleeding = 0
	var/self_delay = 50

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

	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))
		user << "You don't know how to apply \the [src] to [M]..."
		return 1

	if(!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		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)
			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_sel.selecting))
		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"

/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 = 80

/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/
	m_amt = 0
	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"


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), \
	)

/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.0
	force = 9.0
	throwforce = 10.0
	throw_speed = 3
	throw_range = 7
	m_amt = 1000
	max_amount = 60
	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 as obj, mob/user as mob, 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)
			new_item.add_to_stacks(usr)
			user.visible_message("[user.name] shaped [src] into metal with the weldingtool.", \
						 "You shaped [src] into metal with the weldingtool.", \
						 "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/
	m_amt = 0
	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"
	g_amt = MINERAL_MATERIAL_AMOUNT
	origin_tech = "materials=1"

/obj/item/stack/sheet/glass/cyborg
	g_amt = 0
	is_cyborg = 1
	cost = 500

/obj/item/stack/sheet/glass/attack_self(mob/user as mob)
	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)
			RG.add_to_stacks(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 as mob)
	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-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.dir = SOUTHWEST
			W.ini_dir = SOUTHWEST
			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"
	g_amt = MINERAL_MATERIAL_AMOUNT
	m_amt = MINERAL_MATERIAL_AMOUNT / 2
	origin_tech = "materials=2"

/obj/item/stack/sheet/rglass/cyborg
	g_amt = 0
	m_amt = 0
	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(var/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(var/amount)
	metsource.add_charge(amount * metcost)
	glasource.add_charge(amount * glacost)
	return

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

/obj/item/stack/sheet/rglass/proc/construct_window(mob/user as mob)
	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.dir = SOUTHWEST
			W.ini_dir = SOUTHWEST
			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.0
	force = 5.0
	throwforce = 10.0
	item_state = "shard-glass"
	g_amt = MINERAL_MATERIAL_AMOUNT
	attack_verb = list("stabbed", "slashed", "sliced", "cut")
	hitsound = 'sound/weapons/bladeslice.ogg'
	var/cooldown = 0

/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)
			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(var/mob/AM)
	if(istype(AM))
		playsound(loc, 'sound/effects/glass_step.ogg', 50, 1)
		if(ishuman(AM))
			var/mob/living/carbon/human/H = AM
			if(HARDFEET 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

/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

/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 as obj, mob/user as mob, params)
	if(	istype(W, /obj/item/weapon/kitchenknife) || \
		istype(W, /obj/item/weapon/kitchen/utensil/knife) || \
		istype(W, /obj/item/weapon/twohanded/fireaxe) || \
		istype(W, /obj/item/weapon/hatchet) )

		//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
		usr.visible_message("\the [usr] 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))
			usr << "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 usr.loc)
				if(HS.amount < 50)
					HS.amount++
					src.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(usr.loc)
			HS.amount = 1
			src.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_state = "glass_wire"
	w_class = 3.0
	force = 3.0
	throwforce = 5.0
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	max_amount = 60

/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob, 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
		- Diamond
		- Uranium
		- Plasma
		- Gold
		- Silver
		- Clown
	Others:
		- Adamantine
		- Mythril
		- Enriched Uranium
*/

/*
 * Sandstone
 */

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

/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"
	sheettype = "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/New(var/loc, var/amount=null)
	recipes = sandstone_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.0
	throwforce = 5
	w_class = 3.0
	throw_range = 3
	origin_tech = "materials=6"
	sheettype = "diamond"

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.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=5"
	sheettype = "uranium"

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.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "plasmatech=2;materials=2"
	sheettype = "plasma"

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
	..()

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

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.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=3"
	sheettype = "silver"

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.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"
	sheettype = "clown"

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
	..()

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

/*
 * Enriched Uranium
 */
/obj/item/stack/sheet/mineral/enruranium
	name = "enriched uranium"
	icon_state = "sheet-enruranium"
	singular_name = "enriched uranium sheet"
	force = 5.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=5"

/*
 * Adamantine
 */
/obj/item/stack/sheet/mineral/adamantine
	name = "adamantine"
	icon_state = "sheet-adamantine"
	singular_name = "adamantine sheet"
	force = 5.0
	throwforce = 5
	w_class = 3.0
	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.0
	throwforce = 5
	w_class = 3.0
	throw_speed = 1
	throw_range = 3
	origin_tech = "materials=4"


code:
/* Diffrent misc types of sheets
 * Contains:
 *		Metal
 *		Plasteel
 *		Wood
 *		Cloth
 *		Cardboard
 */

/*
 * Metal
 */
var/global/list/datum/stack_recipe/metal_recipes = list ( \
	new/datum/stack_recipe("stool", /obj/structure/stool, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("chair", /obj/structure/stool/bed/chair, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("swivel chair", /obj/structure/stool/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("comfy chair", /obj/structure/stool/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("bed", /obj/structure/stool/bed, 2, one_per_turf = 1, on_floor = 1), \
	null, \
	new/datum/stack_recipe("rack parts", /obj/item/weapon/rack_parts), \
	new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1), \
	null, \
	new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1), \
	null, \
	new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
	new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
	null, \
	new/datum/stack_recipe("computer frame", /obj/structure/computerframe, 5, time = 25, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("machine frame", /obj/machinery/constructable_frame/machine_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1), \
	null, \
	new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade), \
	new/datum/stack_recipe("light fixture frame", /obj/item/light_fixture_frame, 2), \
	new/datum/stack_recipe("small light fixture frame", /obj/item/light_fixture_frame/small, 1), \
	null, \
	new/datum/stack_recipe("apc frame", /obj/item/apc_frame, 2), \
	new/datum/stack_recipe("air alarm frame", /obj/item/alarm_frame, 2), \
	new/datum/stack_recipe("fire alarm frame", /obj/item/firealarm_frame, 2), \
	null, \
	new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = 1, on_floor = 1), \
)

/obj/item/stack/sheet/metal
	name = "metal"
	desc = "Sheets made out of metal."
	singular_name = "metal sheet"
	icon_state = "sheet-metal"
	m_amt = MINERAL_MATERIAL_AMOUNT
	throwforce = 10.0
	flags = CONDUCT
	origin_tech = "materials=1"

/obj/item/stack/sheet/metal/cyborg
	m_amt = 0
	is_cyborg = 1
	cost = 500

/obj/item/stack/sheet/metal/New(var/loc, var/amount=null)
	recipes = metal_recipes
	return ..()

/*
 * Plasteel
 */
var/global/list/datum/stack_recipe/plasteel_recipes = list ( \
	new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1), \
	)

/obj/item/stack/sheet/plasteel
	name = "plasteel"
	singular_name = "plasteel sheet"
	desc = "This sheet is an alloy of iron and plasma."
	icon_state = "sheet-plasteel"
	item_state = "sheet-metal"
	m_amt = 6000
	throwforce = 10.0
	flags = CONDUCT
	origin_tech = "materials=2"

/obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null)
		recipes = plasteel_recipes
		return ..()

/*
 * Wood
 */
var/global/list/datum/stack_recipe/wood_recipes = list ( \
	new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \
	new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
	new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
	new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
	new/datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = 1, on_floor = 1), \
	new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \
	)

/obj/item/stack/sheet/mineral/wood
	name = "wooden plank"
	desc = "One can only guess that this is a bunch of wood."
	singular_name = "wood plank"
	icon_state = "sheet-wood"
	icon = 'icons/obj/items.dmi'
	origin_tech = "materials=1;biotech=1"
	sheettype = "wood"

/obj/item/stack/sheet/mineral/wood/New(var/loc, var/amount=null)
	recipes = wood_recipes
	return ..()

/*
 * Cloth
 */
/obj/item/stack/sheet/cloth
	name = "cloth"
	desc = "This roll of cloth is made from only the finest chemicals and bunny rabbits."
	singular_name = "cloth roll"
	icon_state = "sheet-cloth"
	origin_tech = "materials=2"

/*
 * Cardboard
 */
var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
	new/datum/stack_recipe("box", /obj/item/weapon/storage/box), \
	new/datum/stack_recipe("light tubes", /obj/item/weapon/storage/box/lights/tubes), \
	new/datum/stack_recipe("light bulbs", /obj/item/weapon/storage/box/lights/bulbs), \
	new/datum/stack_recipe("mouse traps", /obj/item/weapon/storage/box/mousetraps), \
	new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
	new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
	new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
	new/datum/stack_recipe("folder", /obj/item/weapon/folder), \
)

/obj/item/stack/sheet/cardboard	//BubbleWrap
	name = "cardboard"
	desc = "Large sheets of card, like boxes folded flat."
	singular_name = "cardboard sheet"
	icon_state = "sheet-card"
	origin_tech = "materials=1"

/obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null)
		recipes = cardboard_recipes
		return ..()


code:
/obj/item/stack/sheet
	name = "sheet"
	w_class = 3.0
	force = 5
	throwforce = 5
	max_amount = 50
	throw_speed = 1
	throw_range = 3
	attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
	var/perunit = MINERAL_MATERIAL_AMOUNT
	var/sheettype = null //this is used for girders in the creation of walls/false walls

// Since the sheetsnatcher was consolidated into weapon/storage/bag we now use
// item/attackby() properly, making this unnecessary

/*/obj/item/stack/sheet/attackby(obj/item/weapon/W as obj, mob/user as mob)
	if (istype(W, /obj/item/weapon/storage/bag/sheetsnatcher))
		var/obj/item/weapon/storage/bag/sheetsnatcher/S = W
		if(!S.mode)
			S.add(src,user)
		else
			for (var/obj/item/stack/sheet/stack in locate(src.x,src.y,src.z))
				S.add(stack,user)
	..()*/


code:
/* Stack type objects!
 * Contains:
 * 		Stacks
 *		Recipe datum
 */

/*
 * Stacks
 */
/obj/item/stack
	origin_tech = "materials=1"
	gender = PLURAL
	var/list/datum/stack_recipe/recipes
	var/singular_name
	var/amount = 1
	var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
	var/is_cyborg = 0 // It's 1 if module is used by a cyborg, and uses its storage
	var/datum/robot_energy_storage/source
	var/cost = 1 // How much energy from storage it costs

/obj/item/stack/New(var/loc, var/amount=null)
	..()
	if (amount)
		src.amount = amount
	return

/obj/item/stack/Destroy()
	if (usr && usr.machine==src)
		usr << browse(null, "window=stack")
	src.loc = null
	..()

/obj/item/stack/examine(mob/user)
	..()
	if (is_cyborg)
		if(src.singular_name)
			user << "There is enough energy for [src.get_amount()] [src.singular_name]\s."
		else
			user << "There is enough energy for [src.get_amount()]."
		return
	if(src.singular_name)
		if(src.get_amount()>1)
			user << "There are [src.get_amount()] [src.singular_name]\s in the stack."
		else
			user << "There is [src.get_amount()] [src.singular_name] in the stack."
	else if(src.get_amount()>1)
		user << "There are [src.get_amount()] in the stack."
	else
		user << "There is [src.get_amount()] in the stack."

/obj/item/stack/proc/get_amount()
	if (is_cyborg)
		return round(source.energy / cost)
	else
		return (amount)

/obj/item/stack/attack_self(mob/user as mob)
	interact(user)

/obj/item/stack/interact(mob/user as mob)
	if (!recipes)
		return
	if (!src || get_amount() <= 0)
		user << browse(null, "window=stack")
	user.set_machine(src) //for correct work of onclose
	var/t1 = text("<title>Constructions from []</title><TT>Amount Left: []
", src, src.get_amount())
	for(var/i=1;i<=recipes.len,i++)
		var/datum/stack_recipe/R = recipes[i]
		if (isnull(R))
			t1 += "
"
			continue
		if (i>1 && !isnull(recipes[i-1]))
			t1+="
"
		var/max_multiplier = round(src.get_amount() / R.req_amount)
		var/title as text
		var/can_build = 1
		can_build = can_build && (max_multiplier>0)
		/*
		if (R.one_per_turf)
			can_build = can_build && !(locate(R.result_type) in usr.loc)
		if (R.on_floor)
			can_build = can_build && istype(usr.loc, /turf/simulated/floor)
		*/
		if (R.res_amount>1)
			title+= "[R.res_amount]x [R.title]\s"
		else
			title+= "[R.title]"
		title+= " ([R.req_amount] [src.singular_name]\s)"
		if (can_build)
			t1 += text("[]  ", src, i, title)
		else
			t1 += text("[]", title)
			continue
		if (R.max_res_amount>1 && max_multiplier>1)
			max_multiplier = min(max_multiplier, round(R.max_res_amount/R.res_amount))
			t1 += " |"
			var/list/multipliers = list(5,10,25)
			for (var/n in multipliers)
				if (max_multiplier>=n)
					t1 += " [n*R.res_amount]x"
			if (!(max_multiplier in multipliers))
				t1 += " [max_multiplier*R.res_amount]x"

	t1 += "</TT>"
	user << browse(t1, "window=stack")
	onclose(user, "stack")
	return

/obj/item/stack/Topic(href, href_list)
	..()
	if ((usr.restrained() || usr.stat || usr.get_active_hand() != src))
		return
	if (href_list["make"])
		if (src.get_amount() < 1) qdel(src) //Never should happen

		var/datum/stack_recipe/R = recipes[text2num(href_list["make"])]
		var/multiplier = text2num(href_list["multiplier"])
		if (!multiplier ||(multiplier <= 0)) //href protection
			return
		if(!building_checks(R, multiplier))
			return
		if (R.time)
			usr << "Building [R.title] ..."
			if (!do_after(usr, R.time))
				return
			if(!building_checks(R, multiplier))
				return

		var/atom/O = new R.result_type( usr.loc )
		O.dir = usr.dir
		use(R.req_amount * multiplier)

		//is it a stack ?
		if (R.max_res_amount > 1)
			var/obj/item/stack/new_item = O
			new_item.amount = R.res_amount*multiplier
			new_item.add_to_stacks(usr) //try to merge with existing stacks on current tile

			if(new_item.amount <= 0)//if the stack is empty, i.e it has been merged with an existing stack and has been garbage collected
				return

		if (istype(O,/obj/item))
			usr.put_in_hands(O)
		O.add_fingerprint(usr)

		//BubbleWrap - so newly formed boxes are empty
		if ( istype(O, /obj/item/weapon/storage) )
			for (var/obj/item/I in O)
				qdel(I)
		//BubbleWrap END

	if (src && usr.machine==src) //do not reopen closed window
		spawn( 0 )
			src.interact(usr)
			return
	return

/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier)
	if (src.get_amount() < R.req_amount*multiplier)
		if (R.req_amount*multiplier>1)
			usr << "You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!"
		else
			usr << "You haven't got enough [src] to build \the [R.title]!"
		return 0
	if (R.one_per_turf && (locate(R.result_type) in usr.loc))
		usr << "There is another [R.title] here!"
		return 0
	if (R.on_floor && !istype(usr.loc, /turf/simulated/floor))
		usr << "\The [R.title] must be constructed on the floor!"
		return 0
	return 1

/obj/item/stack/proc/use(var/used) // return 0 = borked; return 1 = had enough
	if (is_cyborg)
		return source.use_charge(used * cost)
	if (amount < used)
		return 0
	amount -= used
	if (amount <= 0)
		if(usr)
			usr.unEquip(src, 1)
		qdel(src)
	update_icon()
	return 1

/obj/item/stack/proc/add(var/amount)
	if (is_cyborg)
		source.add_charge(amount * cost)
	else
		src.amount += amount
	update_icon()

/obj/item/stack/proc/add_to_stacks(mob/usr as mob)
	var/obj/item/stack/oldsrc = src
	src = null
	for (var/obj/item/stack/item in usr.loc)
		if (item==oldsrc)
			continue
		if (!istype(item, oldsrc.type))
			continue
		if (item.amount>=item.max_amount)
			continue
		oldsrc.attackby(item, usr)
		usr << "You add new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s."
		if(oldsrc.amount <= 0)
			break
	oldsrc.update_icon()

/obj/item/stack/attack_hand(mob/user as mob)
	if (user.get_inactive_hand() == src)
		var/obj/item/stack/F = new src.type( user, 1)
		F.copy_evidences(src)
		user.put_in_hands(F)
		src.add_fingerprint(user)
		F.add_fingerprint(user)
		use(1)
		if (src && usr.machine==src)
			spawn(0) src.interact(usr)
	else
		..()
	return

/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob, params)

	if (istype(W, src.type))
		var/obj/item/stack/S = W
		if (S.is_cyborg)
			var/to_transfer = min(src.amount, round((S.source.max_energy - S.source.energy) / S.cost))
			S.add(to_transfer)
			if (S && usr.machine==S)
				spawn(0) S.interact(usr)
			src.use(to_transfer)
			if (src && usr.machine==src)
				spawn(0) src.interact(usr)
		else
			if (S.amount >= max_amount)
				return
			var/to_transfer as num
			if (user.get_inactive_hand()==src)
				to_transfer = 1
			else
				to_transfer = min(src.amount, S.max_amount-S.amount)
			S.amount+=to_transfer
			if (S && usr.machine==S)
				spawn(0) S.interact(usr)
			src.use(to_transfer)
			if (src && usr.machine==src)
				spawn(0) src.interact(usr)
			S.update_icon()

	else
		..()

/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
	src.blood_DNA = from.blood_DNA
	src.fingerprints  = from.fingerprints
	src.fingerprintshidden  = from.fingerprintshidden
	src.fingerprintslast  = from.fingerprintslast
	//TODO bloody overlay

/*
 * Recipe datum
 */
/datum/stack_recipe
	var/title = "ERROR"
	var/result_type
	var/req_amount = 1
	var/res_amount = 1
	var/max_res_amount = 1
	var/time = 0
	var/one_per_turf = 0
	var/on_floor = 0
	New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0)
		src.title = title
		src.result_type = result_type
		src.req_amount = req_amount
		src.res_amount = res_amount
		src.max_res_amount = max_res_amount
		src.time = time
		src.one_per_turf = one_per_turf
		src.on_floor = on_floor


code:
/obj/item/stack/tile/light
	name = "light tile"
	singular_name = "light floor tile"
	desc = "A floor tile, made out of glass. It produces light."
	icon_state = "tile_e"
	w_class = 3.0
	force = 3.0
	throwforce = 5.0
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	max_amount = 60
	attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
	turf_type = /turf/simulated/floor/light
	var/state = 0

/obj/item/stack/tile/light/New(var/loc, var/amount=null)
	..()
	if(prob(5))
		state = 3 //broken
	else if(prob(5))
		state = 2 //breaking
	else if(prob(10))
		state = 1 //flickering occasionally
	else
		state = 0 //fine

/obj/item/stack/tile/light/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
	..()
	if(istype(O,/obj/item/weapon/crowbar))
		new/obj/item/stack/sheet/metal(user.loc)
		amount--
		new/obj/item/stack/light_w(user.loc)
		if(amount <= 0)
			user.unEquip(src, 1)
			qdel(src)


code:
/obj/item/stack/tile

/obj/item/stack/tile/plasteel
	name = "floor tile"
	singular_name = "floor tile"
	desc = "Those could work as a pretty decent throwing weapon"
	icon_state = "tile"
	w_class = 3.0
	force = 6.0
	m_amt = 937.5
	throwforce = 10.0
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	max_amount = 60
	turf_type = /turf/simulated/floor/plasteel
	mineralType = "metal"

/obj/item/stack/tile/plasteel/cyborg
	desc = "The ground you walk on" //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR
	m_amt = 0 // All other Borg versions of items have no Metal or Glass - RR
	is_cyborg = 1
	cost = 125

/obj/item/stack/tile/plasteel/New(var/loc, var/amount=null)
	..()
	src.pixel_x = rand(1, 14)
	src.pixel_y = rand(1, 14)
	return