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

var/list/preferences_datums = list()

var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm
//some autodetection here.
	"traitor" = /datum/game_mode/traitor,			//0
	"operative" = /datum/game_mode/nuclear,			//1
	"changeling" = /datum/game_mode/changeling,		//2
	"wizard" = /datum/game_mode/wizard,				//3
	"malf AI" = /datum/game_mode/malfunction,		//4
	"revolutionary" = /datum/game_mode/revolution,	//5
	"alien",										//6
	"pAI/posibrain",								//7
	"cultist" = /datum/game_mode/cult,				//8
	"blob" = /datum/game_mode/blob,					//9
	"ninja",										//10
	"monkey" = /datum/game_mode/monkey,				//11
	"gangster" = /datum/game_mode/gang,				//12
	"shadowling" = /datum/game_mode/shadowling,		//13
	"abductor" = /datum/game_mode/abduction			//14
)

datum/preferences
	//doohickeys for savefiles
	var/path
	var/default_slot = 1				//Holder so it doesn't default to slot 1, rather the last one used
	var/max_save_slots = 3

	//non-preference stuff
	var/muted = 0
	var/last_ip
	var/last_id

	//game-preferences
	var/lastchangelog = ""				//Saved changlog filesize to detect if there was a change
	var/ooccolor = "#002eb8"
	var/be_special = 0					//Special role selection
	var/UI_style = "Midnight"
	var/toggles = TOGGLES_DEFAULT
	var/chat_toggles = TOGGLES_DEFAULT_CHAT
	var/ghost_form = "ghost"
	var/allow_midround_antag = 1

	//character preferences
	var/real_name						//our character's name
	var/be_random_name = 0				//whether we'll have a random name every round
	var/be_random_body = 0				//whether we'll have a random body every round
	var/gender = MALE					//gender of character (well duh)
	var/age = 30						//age of character
	var/blood_type = "A+"				//blood type (not-chooseable)
	var/underwear = "Nude"				//underwear type
	var/undershirt = "Nude"				//undershirt type
	var/socks = "Nude"					//socks type
	var/backbag = 2						//backpack type
	var/hair_style = "Bald"				//Hair type
	var/hair_color = "000"				//Hair color
	var/facial_hair_style = "Shaved"	//Face hair type
	var/facial_hair_color = "000"		//Facial hair color
	var/skin_tone = "caucasian1"		//Skin color
	var/eye_color = "000"				//Eye color
	var/datum/species/pref_species = new /datum/species/human()	//Mutant race
	var/mutant_color = "FFF"			//Mutant race skin color

		//Mob preview
	var/icon/preview_icon_front = null
	var/icon/preview_icon_side = null

		//Jobs, uses bitflags
	var/job_civilian_high = 0
	var/job_civilian_med = 0
	var/job_civilian_low = 0

	var/job_medsci_high = 0
	var/job_medsci_med = 0
	var/job_medsci_low = 0

	var/job_engsec_high = 0
	var/job_engsec_med = 0
	var/job_engsec_low = 0

		// Want randomjob if preferences already filled - Donkie
	var/userandomjob = 1 //defaults to 1 for fewer assistants

	// 0 = character settings, 1 = game preferences
	var/current_tab = 0

		// OOC Metadata:
	var/metadata = ""

	var/unlock_content = 0

/datum/preferences/New(client/C)
	blood_type = random_blood_type()
	ooccolor = normal_ooc_colour
	if(istype(C))
		if(!IsGuestKey(C.key))
			load_path(C.ckey)
			unlock_content = C.IsByondMember()
			if(unlock_content)
				max_save_slots = 8
	var/loaded_preferences_successfully = load_preferences()
	if(loaded_preferences_successfully)
		if(load_character())
			return
	//we couldn't load character data so just randomize the character appearance + name
	random_character()		//let's create a random character then - rather than a fat, bald and naked man.
	real_name = random_name(gender)
	if(!loaded_preferences_successfully)
		save_preferences()
	save_character()		//let's save this new random character so it doesn't keep generating new ones.
	return

/datum/preferences
	proc/ShowChoices(mob/user)
		if(!user || !user.client)	return
		update_preview_icon()
		user << browse_rsc(preview_icon_front, "previewicon.png")
		user << browse_rsc(preview_icon_side, "previewicon2.png")
		var/dat = ""

		dat += "Character Settings "
		dat += "Game Preferences"

		if(!path)
			dat += "
Please create an account to save your preferences
"

		dat += ""

		dat += "
"

		switch(current_tab)
			if (0) // Character Settings#
				if(path)
					var/savefile/S = new /savefile(path)
					if(S)
						dat += ""
						var/name
						for(var/i=1, i<=max_save_slots, i++)
							S.cd = "/character[i]"
							S["real_name"] >> name
							if(!name)	name = "Character[i]"
							//if(i!=1) dat += " | "
							dat += "[name] "
						dat += ""

				dat += "
Occupation Choices
"
				dat += "Set Occupation Preferences
"
				dat += "
Identity
"
				dat += "

"
				if(appearance_isbanned(user))
					dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
"
				dat += "Random Name "
				dat += "Always Random Name: [be_random_name ? "Yes" : "No"]
"

				dat += "Name: "
				dat += "[real_name]
"

				dat += "Gender: [gender == MALE ? "Male" : "Female"]
"
				dat += "Age: [age]"

				dat += "	"

				dat += "

"

				dat += "

"

				dat += "
Body
"
				dat += "Random Body "
				dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
"

				dat += "

"

				if(config.mutant_races)
					dat += "Species:
[pref_species.name]
"
				else
					dat += "Species: Human
"

				dat += "Blood Type: [blood_type]
"
				dat += "Underwear:
[underwear]
"
				dat += "Undershirt:
[undershirt]
"
				dat += "Socks:
[socks]
"
				dat += "Backpack:
[backbaglist[backbag]]
"

				if(pref_species.use_skintones)

					dat += "	"

					dat += "
Skin Tone
"

					dat += "[skin_tone]
"

					dat += "	"

				if(HAIR in pref_species.specflags)

					dat += ""

					dat += "
Hair Style
"

					dat += "[hair_style]
"
					dat += "< >
"
					dat += "    Change
"

					dat += "	"

					dat += "
Facial Hair Style
"

					dat += "[facial_hair_style]
"
					dat += "< >
"
					dat += "    Change
"

					dat += "	"

				if(EYECOLOR in pref_species.specflags)

					dat += ""

					dat += "
Eye Color
"

					dat += "    Change
"

					dat += "	"

				if(MUTCOLORS in pref_species.specflags)

					dat += ""

					dat += "
Alien Color
"

					dat += "    Change
"

					dat += "	"

				dat += "

"

			if (1) // Game Preferences
				dat += "

"
				dat += "
General Settings
"
				dat += "UI Style: [UI_style]
"
				dat += "Play admin midis: [(toggles & SOUND_MIDI) ? "Yes" : "No"]
"
				dat += "Play lobby music: [(toggles & SOUND_LOBBY) ? "Yes" : "No"]
"
				dat += "Ghost ears: [(chat_toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]
"
				dat += "Ghost sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]
"
				dat += "Ghost whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "Nearest Creatures" : "All Speech"]
"
				dat += "Ghost radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]
"
				dat += "Ghost pda: [(chat_toggles & CHAT_GHOSTPDA) ? "Nearest Creatures" : "All Messages"]
"
				dat += "Pull requests: [(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]
"
				dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]
"
				if(config.allow_Metadata)
					dat += "OOC Notes:  Edit
"

				if(user.client)
					if(user.client.holder)
						dat += "Adminhelp Sound: "
						dat += "[(toggles & SOUND_ADMINHELP)?"On":"Off"]
"

					if(unlock_content || check_rights_for(user.client, R_ADMIN))
						dat += "OOC:     Change
"

					if(unlock_content)
						dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
"
						dat += "Ghost Form: [ghost_form]
"

				dat += "	"

				dat += "
Antagonist Settings
"

				if(jobban_isbanned(user, "Syndicate"))
					dat += "You are banned from antagonist roles."
					src.be_special = 0

				else
					var/n = 0
					for (var/i in special_roles)
						if(jobban_isbanned(user, i))
							dat += "Be [i]: \[BANNED]
"
						else
							var/days_remaining = null
							if(config.use_age_restriction_for_jobs && ispath(special_roles[i])) //If it's a game mode antag, check if the player meets the minimum age
								var/mode_path = special_roles[i]
								var/datum/game_mode/temp_mode = new mode_path
								days_remaining = temp_mode.get_remaining_days(user.client)

							if(days_remaining)
								dat += "Be [i]:  \[IN [days_remaining] DAYS]
"
							else
								dat += "Be [i]: [src.be_special&(1<<n) ? "Yes" : "No"]
"
						n++
				dat += "

"

		dat += "
"

		if(!IsGuestKey(user.key))
			dat += "Undo "
			dat += "Save Setup "

		dat += "Reset Setup"
		dat += ""

		//user << browse(dat, "window=preferences;size=560x560")
		var/datum/browser/popup = new(user, "preferences", "
Character Setup
", 640, 680)
		popup.set_content(dat)
		popup.open(0)

	proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620)
		if(!SSjob)	return

		//limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
		//splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice.
		//widthPerColumn - Screen's width for every column.
		//height - Screen's height.

		var/width = widthPerColumn

		var/HTML = ""
		HTML += "Choose occupation chances
"
		HTML += "
Left-click to raise an occupation preference, right-click to lower it.

"
		HTML += "Done
" // Easier to press up here.
		HTML += ""
		HTML += "

" // Table within a table for alignment, also allows you to easily add more colomns.
		HTML += "
"
		var/index = -1

		//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
		var/datum/job/lastJob

		for(var/datum/job/job in SSjob.occupations)

			index += 1
			if((index >= limit) || (job.title in splitJobs))
				width += widthPerColumn
				if((index < limit) && (lastJob != null))
					//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
					//the last job's selection color. Creating a rather nice effect.
					for(var/i = 0, i < (limit - index), i += 1)
						HTML += "
&nbsp	&nbsp
"
				HTML += "

"
				index = 0

			HTML += "
"
			var/rank = job.title
			lastJob = job
			if(jobban_isbanned(user, rank))
				HTML += "[rank]	 \[BANNED\]
"
				continue
			if(!job.player_old_enough(user.client))
				var/available_in_days = job.available_in_days(user.client)
				HTML += "[rank]	 \[IN [(available_in_days)] DAYS\]
"
				continue
			if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant"))
				HTML += "[rank]
"
				continue
			if(config.enforce_human_authority && (rank in command_positions) && user.client.prefs.pref_species.id != "human")
				HTML += "[rank]	 \[NON-HUMAN\]
"
				continue
			if((rank in command_positions) || (rank == "AI"))//Bold head jobs
				HTML += "[rank]"
			else
				HTML += "[rank]"

			HTML += "	"

			var/prefLevelLabel = "ERROR"
			var/prefLevelColor = "pink"
			var/prefUpperLevel = -1 // level to assign on left click
			var/prefLowerLevel = -1 // level to assign on right click

			if(GetJobDepartment(job, 1) & job.flag)
				prefLevelLabel = "High"
				prefLevelColor = "slateblue"
				prefUpperLevel = 4
				prefLowerLevel = 2
			else if(GetJobDepartment(job, 2) & job.flag)
				prefLevelLabel = "Medium"
				prefLevelColor = "green"
				prefUpperLevel = 1
				prefLowerLevel = 3
			else if(GetJobDepartment(job, 3) & job.flag)
				prefLevelLabel = "Low"
				prefLevelColor = "orange"
				prefUpperLevel = 2
				prefLowerLevel = 4
			else
				prefLevelLabel = "NEVER"
				prefLevelColor = "red"
				prefUpperLevel = 3
				prefLowerLevel = 1

			HTML += ""

			if(rank == "Assistant")//Assistant is special
				if(job_civilian_low & ASSISTANT)
					HTML += "Yes"
				else
					HTML += "No"
				HTML += "
"
				continue

			HTML += "[prefLevelLabel]"
			HTML += "
"

		for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
			if(lastJob)
				HTML += "
&nbsp	&nbsp
"

		HTML += "

"

		HTML += "
"

		HTML += "
[userandomjob ? "Get random job if preferences unavailable" : "Be an Assistant if preference unavailable"]"
		HTML += "Reset Preferences"

		user << browse(null, "window=preferences")
		//user << browse(HTML, "window=mob_occupation;size=[width]x[height]")
		var/datum/browser/popup = new(user, "mob_occupation", "
Occupation Preferences
", width, height)
		popup.set_window_options("can_close=0")
		popup.set_content(HTML)
		popup.open(0)
		return

	proc/SetJobPreferenceLevel(var/datum/job/job, var/level)
		if (!job)
			return 0

		if (level == 1) // to high
			// remove any other job(s) set to high
			job_civilian_med |= job_civilian_high
			job_engsec_med |= job_engsec_high
			job_medsci_med |= job_medsci_high
			job_civilian_high = 0
			job_engsec_high = 0
			job_medsci_high = 0

		if (job.department_flag == CIVILIAN)
			job_civilian_low &= ~job.flag
			job_civilian_med &= ~job.flag
			job_civilian_high &= ~job.flag

			switch(level)
				if (1)
					job_civilian_high |= job.flag
				if (2)
					job_civilian_med |= job.flag
				if (3)
					job_civilian_low |= job.flag

			return 1
		else if (job.department_flag == ENGSEC)
			job_engsec_low &= ~job.flag
			job_engsec_med &= ~job.flag
			job_engsec_high &= ~job.flag

			switch(level)
				if (1)
					job_engsec_high |= job.flag
				if (2)
					job_engsec_med |= job.flag
				if (3)
					job_engsec_low |= job.flag

			return 1
		else if (job.department_flag == MEDSCI)
			job_medsci_low &= ~job.flag
			job_medsci_med &= ~job.flag
			job_medsci_high &= ~job.flag

			switch(level)
				if (1)
					job_medsci_high |= job.flag
				if (2)
					job_medsci_med |= job.flag
				if (3)
					job_medsci_low |= job.flag

			return 1

		return 0

	proc/UpdateJobPreference(mob/user, role, desiredLvl)
		if(!SSjob)
			return
		var/datum/job/job = SSjob.GetJob(role)

		if(!job)
			user << browse(null, "window=mob_occupation")
			ShowChoices(user)
			return

		if (!isnum(desiredLvl))
			user << "UpdateJobPreference - desired level was not a number. Please notify coders!"
			ShowChoices(user)
			return

		if(role == "Assistant")
			if(job_civilian_low & job.flag)
				job_civilian_low &= ~job.flag
			else
				job_civilian_low |= job.flag
			SetChoices(user)
			return 1

		SetJobPreferenceLevel(job, desiredLvl)
		SetChoices(user)

		return 1

	proc/ResetJobs()

		job_civilian_high = 0
		job_civilian_med = 0
		job_civilian_low = 0

		job_medsci_high = 0
		job_medsci_med = 0
		job_medsci_low = 0

		job_engsec_high = 0
		job_engsec_med = 0
		job_engsec_low = 0

	proc/GetJobDepartment(var/datum/job/job, var/level)
		if(!job || !level)	return 0
		switch(job.department_flag)
			if(CIVILIAN)
				switch(level)
					if(1)
						return job_civilian_high
					if(2)
						return job_civilian_med
					if(3)
						return job_civilian_low
			if(MEDSCI)
				switch(level)
					if(1)
						return job_medsci_high
					if(2)
						return job_medsci_med
					if(3)
						return job_medsci_low
			if(ENGSEC)
				switch(level)
					if(1)
						return job_engsec_high
					if(2)
						return job_engsec_med
					if(3)
						return job_engsec_low
		return 0

	proc/process_link(mob/user, list/href_list)
		if(!istype(user, /mob/new_player))	return

		if(href_list["preference"] == "job")
			switch(href_list["task"])
				if("close")
					user << browse(null, "window=mob_occupation")
					ShowChoices(user)
				if("reset")
					ResetJobs()
					SetChoices(user)
				if("random")
					if(jobban_isbanned(user, "Assistant"))
						userandomjob = 1
					else
						userandomjob = !userandomjob
					SetChoices(user)
				if("setJobLevel")
					UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
				else
					SetChoices(user)
			return 1

		switch(href_list["task"])
			if("random")
				switch(href_list["preference"])
					if("name")
						real_name = random_name(gender)
					if("age")
						age = rand(AGE_MIN, AGE_MAX)
					if("hair")
						hair_color = random_short_color()
					if("hair_style")
						hair_style = random_hair_style(gender)
					if("facial")
						facial_hair_color = random_short_color()
					if("facial_hair_style")
						facial_hair_style = random_facial_hair_style(gender)
					if("underwear")
						underwear = random_underwear(gender)
					if("undershirt")
						undershirt = random_undershirt(gender)
					if("socks")
						socks = random_socks(gender)
					if("eyes")
						eye_color = random_eye_color()
					if("s_tone")
						skin_tone = random_skin_tone()
					if("bag")
						backbag = rand(1,3)
					if("all")
						random_character()

			if("input")
				switch(href_list["preference"])
					if("ghostform")
						if(unlock_content)
							var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in ghost_forms
							if(new_form)
								ghost_form = new_form
					if("name")
						var/new_name = reject_bad_name( input(user, "Choose your character's name:", "Character Preference")  as text|null )
						if(new_name)
							real_name = new_name
						else
							user << "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."

					if("age")
						var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
						if(new_age)
							age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)

					if("metadata")
						var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata)  as message|null
						if(new_metadata)
							metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))

					if("hair")
						var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as null|color
						if(new_hair)
							hair_color = sanitize_hexcolor(new_hair)

					if("hair_style")
						var/new_hair_style
						if(gender == MALE)
							new_hair_style = input(user, "Choose your character's hair style:", "Character Preference")  as null|anything in hair_styles_male_list
						else
							new_hair_style = input(user, "Choose your character's hair style:", "Character Preference")  as null|anything in hair_styles_female_list
						if(new_hair_style)
							hair_style = new_hair_style

					if("next_hair_style")
						if (gender == MALE)
							hair_style = next_list_item(hair_style, hair_styles_male_list)
						else
							hair_style = next_list_item(hair_style, hair_styles_female_list)

					if("previous_hair_style")
						if (gender == MALE)
							hair_style = previous_list_item(hair_style, hair_styles_male_list)
						else
							hair_style = previous_list_item(hair_style, hair_styles_female_list)

					if("facial")
						var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as null|color
						if(new_facial)
							facial_hair_color = sanitize_hexcolor(new_facial)

					if("facial_hair_style")
						var/new_facial_hair_style
						if(gender == MALE)
							new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference")  as null|anything in facial_hair_styles_male_list
						else
							new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference")  as null|anything in facial_hair_styles_female_list
						if(new_facial_hair_style)
							facial_hair_style = new_facial_hair_style

					if("next_facehair_style")
						if (gender == MALE)
							facial_hair_style = next_list_item(facial_hair_style, facial_hair_styles_male_list)
						else
							facial_hair_style = next_list_item(facial_hair_style, facial_hair_styles_female_list)

					if("previous_facehair_style")
						if (gender == MALE)
							facial_hair_style = previous_list_item(facial_hair_style, facial_hair_styles_male_list)
						else
							facial_hair_style = previous_list_item(facial_hair_style, facial_hair_styles_female_list)

					if("underwear")
						var/new_underwear
						if(gender == MALE)
							new_underwear = input(user, "Choose your character's underwear:", "Character Preference")  as null|anything in underwear_m
						else
							new_underwear = input(user, "Choose your character's underwear:", "Character Preference")  as null|anything in underwear_f
						if(new_underwear)
							underwear = new_underwear

					if("undershirt")
						var/new_undershirt
						if(gender == MALE)
							new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_m
						else
							new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_f
						if(new_undershirt)
							undershirt = new_undershirt

					if("socks")
						var/new_socks
						if(gender == MALE)
							new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in socks_m
						else
							new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in socks_f
						if(new_socks)
							socks = new_socks

					if("eyes")
						var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null
						if(new_eyes)
							eye_color = sanitize_hexcolor(new_eyes)

					if("species")

						var/result = input(user, "Select a species", "Species Selection") as null|anything in roundstart_species

						if(result)
							var/newtype = roundstart_species[result]
							pref_species = new newtype()
							if(!config.mutant_colors || mutant_color == "#000")
								mutant_color = pref_species.default_color

					if("mutant_color")
						if(!config.mutant_colors)
							user << "Alien colors are disabled."
							return
						var/new_mutantcolor = input(user, "Choose your character's alien skin color:", "Character Preference") as color|null
						if(new_mutantcolor)
							var/temp_hsv = RGBtoHSV(new_mutantcolor)
							if(new_mutantcolor == "#000000")
								mutant_color = pref_species.default_color
							else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
								mutant_color = sanitize_hexcolor(new_mutantcolor)
							else
								user << "Invalid color. Your color is not bright enough."

					if("s_tone")
						var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference")  as null|anything in skin_tones
						if(new_s_tone)
							skin_tone = new_s_tone

					if("ooccolor")
						var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
						if(new_ooccolor)
							ooccolor = sanitize_ooccolor(new_ooccolor)

					if("bag")
						var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference")  as null|anything in backbaglist
						if(new_backbag)
							backbag = backbaglist.Find(new_backbag)
			else
				switch(href_list["preference"])
					if("publicity")
						if(unlock_content)
							toggles ^= MEMBER_PUBLIC
					if("gender")
						if(gender == MALE)
							gender = FEMALE
						else
							gender = MALE
						underwear = random_underwear(gender)
						undershirt = random_undershirt(gender)
						socks = random_socks(gender)
						facial_hair_style = random_facial_hair_style(gender)
						hair_style = random_hair_style(gender)

					if("hear_adminhelps")
						toggles ^= SOUND_ADMINHELP

					if("ui")
						switch(UI_style)
							if("Midnight")
								UI_style = "Plasmafire"
							if("Plasmafire")
								UI_style = "Retro"
							else
								UI_style = "Midnight"

					if("be_special")
						var/num = text2num(href_list["num"])
						be_special ^= (1<<num)

					if("name")
						be_random_name = !be_random_name

					if("all")
						be_random_body = !be_random_body

					if("hear_midis")
						toggles ^= SOUND_MIDI

					if("lobby_music")
						toggles ^= SOUND_LOBBY
						if(toggles & SOUND_LOBBY)
							user << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1)
						else
							user << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1)

					if("ghost_ears")
						chat_toggles ^= CHAT_GHOSTEARS

					if("ghost_sight")
						chat_toggles ^= CHAT_GHOSTSIGHT

					if("ghost_whispers")
						chat_toggles ^= CHAT_GHOSTWHISPER

					if("ghost_radio")
						chat_toggles ^= CHAT_GHOSTRADIO

					if("ghost_pda")
						chat_toggles ^= CHAT_GHOSTPDA

					if("pull_requests")
						chat_toggles ^= CHAT_PULLR

					if("allow_midround_antag")
						toggles ^= MIDROUND_ANTAG

					if("save")
						save_preferences()
						save_character()

					if("load")
						load_preferences()
						load_character()

					if("changeslot")
						if(!load_character(text2num(href_list["num"])))
							random_character()
							real_name = random_name(gender)
							save_character()

					if("tab")
						if (href_list["tab"])
							current_tab = text2num(href_list["tab"])

		ShowChoices(user)
		return 1

	proc/copy_to(mob/living/carbon/human/character)
		if(be_random_name)
			real_name = random_name(gender)

		if(be_random_body)
			random_character(gender)

		if(config.humans_need_surnames)
			var/firstspace = findtext(real_name, " ")
			var/name_length = length(real_name)
			if(!firstspace)	//we need a surname
				real_name += " [pick(last_names)]"
			else if(firstspace == name_length)
				real_name += "[pick(last_names)]"

		character.real_name = real_name
		character.name = character.real_name

		if(character.dna)
			character.dna.real_name = character.real_name
			if(pref_species != /datum/species/human && config.mutant_races)
				hardset_dna(character, null, null, null, null, pref_species.type)
			else
				hardset_dna(character, null, null, null, null, /datum/species/human)
			character.dna.mutant_color = mutant_color
			character.update_mutcolor()

		character.gender = gender
		character.age = age
		character.blood_type = blood_type

		character.eye_color = eye_color
		character.hair_color = hair_color
		character.facial_hair_color = facial_hair_color

		character.skin_tone = skin_tone
		character.hair_style = hair_style
		character.facial_hair_style = facial_hair_style
		character.underwear = underwear
		character.undershirt = undershirt
		character.socks = socks

		if(backbag > 3 || backbag < 1)
			backbag = 1 //Same as above
		character.backbag = backbag

		/*
		//Debugging report to track down a bug, which randomly assigned the plural gender to people.
		if(character.gender in list(PLURAL, NEUTER))
			if(isliving(src)) //Ghosts get neuter by default
				message_admins("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.")
				character.gender = MALE
		*/


code:
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
#define SAVEFILE_VERSION_MIN	8

//This is the current version, anything below this will attempt to update (if it's not obsolete)
#define SAVEFILE_VERSION_MAX	10
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
	This proc checks if the current directory of the savefile S needs updating
	It is to be used by the load_character and load_preferences procs.
	(S.cd=="/" is preferences, S.cd=="/character[integer]" is a character slot, etc)

	if the current directory's version is below SAVEFILE_VERSION_MIN it will simply wipe everything in that directory
	(if we're at root "/" then it'll just wipe the entire savefile, for instance.)

	if its version is below SAVEFILE_VERSION_MAX but above the minimum, it will load data but later call the
	respective update_preferences() or update_character() proc.
	Those procs allow coders to specify format changes so users do not lose their setups and have to redo them again.

	Failing all that, the standard sanity checks are performed. They simply check the data is suitable, reverting to
	initial() values if necessary.
*/
/datum/preferences/proc/savefile_needs_update(savefile/S)
	var/savefile_version
	S["version"] >> savefile_version

	if(savefile_version < SAVEFILE_VERSION_MIN)
		S.dir.Cut()
		return -2
	if(savefile_version < SAVEFILE_VERSION_MAX)
		return savefile_version
	return -1

/datum/preferences/proc/update_preferences(current_version)
	if(current_version < 10)
		toggles |= MEMBER_PUBLIC
	return

//should this proc get fairly long (say 3 versions long),
//just increase SAVEFILE_VERSION_MIN so it's not as far behind
//SAVEFILE_VERSION_MAX and then delete any obsolete if clauses
//from this proc.
//It's only really meant to avoid annoying frequent players
//if your savefile is 3 months out of date, then 'tough shit'.
/datum/preferences/proc/update_character(current_version)
	if(current_version < 9)		//an example, underwear were an index for a hardcoded list, converting to a string
		if(gender == MALE)
			switch(underwear)
				if(1)	underwear = "Mens White"
				if(2)	underwear = "Mens Grey"
				if(3)	underwear = "Mens Green"
				if(4)	underwear = "Mens Blue"
				if(5)	underwear = "Mens Black"
				if(6)	underwear = "Mankini"
				if(7)	underwear = "Mens Hearts Boxer"
				if(8)	underwear = "Mens Black Boxer"
				if(9)	underwear = "Mens Grey Boxer"
				if(10)	underwear = "Mens Striped Boxer"
				if(11)	underwear = "Mens Kinky"
				if(12)	underwear = "Mens Red"
				if(13)	underwear = "Nude"
		else
			switch(underwear)
				if(1)	underwear = "Ladies Red"
				if(2)	underwear = "Ladies White"
				if(3)	underwear = "Ladies Yellow"
				if(4)	underwear = "Ladies Blue"
				if(5)	underwear = "Ladies Black"
				if(6)	underwear = "Ladies Thong"
				if(7)	underwear = "Babydoll"
				if(8)	underwear = "Ladies Baby-Blue"
				if(9)	underwear = "Ladies Green"
				if(10)	underwear = "Ladies Pink"
				if(11)	underwear = "Ladies Kinky"
				if(12)	underwear = "Tankini"
				if(13)	underwear = "Nude"
		if(!(pref_species in species_list))
			pref_species = new /datum/species/human()
	return

/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
	if(!ckey)	return
	path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[filename]"

/datum/preferences/proc/load_preferences()
	if(!path)				return 0
	if(!fexists(path))		return 0

	var/savefile/S = new /savefile(path)
	if(!S)					return 0
	S.cd = "/"

	var/needs_update = savefile_needs_update(S)
	if(needs_update == -2)		//fatal, can't load any data
		return 0

	//general preferences
	S["ooccolor"]			>> ooccolor
	S["lastchangelog"]		>> lastchangelog
	S["UI_style"]			>> UI_style
	S["be_special"]			>> be_special
	S["default_slot"]		>> default_slot
	S["chat_toggles"]		>> chat_toggles
	S["toggles"]			>> toggles
	S["ghost_form"]			>> ghost_form

	//try to fix any outdated data if necessary
	if(needs_update >= 0)
		update_preferences(needs_update)		//needs_update = savefile_version if we need an update (positive integer)

	//Sanitize
	ooccolor		= sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
	lastchangelog	= sanitize_text(lastchangelog, initial(lastchangelog))
	UI_style		= sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro"), initial(UI_style))
	be_special		= sanitize_integer(be_special, 0, 65535, initial(be_special))
	default_slot	= sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
	toggles			= sanitize_integer(toggles, 0, 65535, initial(toggles))
	ghost_form		= sanitize_inlist(ghost_form, ghost_forms, initial(ghost_form))

	return 1

/datum/preferences/proc/save_preferences()
	if(!path)				return 0
	var/savefile/S = new /savefile(path)
	if(!S)					return 0
	S.cd = "/"

	S["version"] << SAVEFILE_VERSION_MAX		//updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date

	//general preferences
	S["ooccolor"]			<< ooccolor
	S["lastchangelog"]		<< lastchangelog
	S["UI_style"]			<< UI_style
	S["be_special"]			<< be_special
	S["default_slot"]		<< default_slot
	S["toggles"]			<< toggles
	S["chat_toggles"]		<< chat_toggles
	S["ghost_form"]			<< ghost_form

	return 1

/datum/preferences/proc/load_character(slot)
	if(!path)				return 0
	if(!fexists(path))		return 0
	var/savefile/S = new /savefile(path)
	if(!S)					return 0
	S.cd = "/"
	if(!slot)	slot = default_slot
	slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot))
	if(slot != default_slot)
		default_slot = slot
		S["default_slot"] << slot

	S.cd = "/character[slot]"
	var/needs_update = savefile_needs_update(S)
	if(needs_update == -2)		//fatal, can't load any data
		return 0

	//Species
	var/species_name
	S["species"]			>> species_name
	if(config.mutant_races && species_name && (species_name in roundstart_species))
		var/newtype = roundstart_species[species_name]
		pref_species = new newtype()
	else
		pref_species = new /datum/species/human()

	if(!S["mutant_color"] || S["mutant_color"] == "#000")
		S["mutant_color"]	<< "#FFF"

	//Character
	S["OOC_Notes"]			>> metadata
	S["real_name"]			>> real_name
	S["name_is_always_random"] >> be_random_name
	S["body_is_always_random"] >> be_random_body
	S["gender"]				>> gender
	S["age"]				>> age
	S["hair_color"]			>> hair_color
	S["facial_hair_color"]	>> facial_hair_color
	S["eye_color"]			>> eye_color
	S["skin_tone"]			>> skin_tone
	S["hair_style_name"]	>> hair_style
	S["facial_style_name"]	>> facial_hair_style
	S["underwear"]			>> underwear
	S["undershirt"]			>> undershirt
	S["socks"]				>> socks
	S["backbag"]			>> backbag
	S["mutant_color"]		>> mutant_color

	//Jobs
	S["userandomjob"]		>> userandomjob
	S["job_civilian_high"]	>> job_civilian_high
	S["job_civilian_med"]	>> job_civilian_med
	S["job_civilian_low"]	>> job_civilian_low
	S["job_medsci_high"]	>> job_medsci_high
	S["job_medsci_med"]		>> job_medsci_med
	S["job_medsci_low"]		>> job_medsci_low
	S["job_engsec_high"]	>> job_engsec_high
	S["job_engsec_med"]		>> job_engsec_med
	S["job_engsec_low"]		>> job_engsec_low

	//try to fix any outdated data if necessary
	if(needs_update >= 0)
		update_character(needs_update)		//needs_update == savefile_version if we need an update (positive integer)

	//Sanitize
	metadata		= sanitize_text(metadata, initial(metadata))
	real_name		= reject_bad_name(real_name)
	if(!mutant_color || mutant_color == "#000")
		mutant_color = "#FFF"
	if(!real_name)	real_name = random_name(gender)
	be_random_name	= sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
	be_random_body	= sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
	gender			= sanitize_gender(gender)
	if(gender == MALE)
		hair_style			= sanitize_inlist(hair_style, hair_styles_male_list)
		facial_hair_style			= sanitize_inlist(facial_hair_style, facial_hair_styles_male_list)
		underwear		= sanitize_inlist(underwear, underwear_m)
		undershirt 		= sanitize_inlist(undershirt, undershirt_m)
		socks			= sanitize_inlist(socks, socks_m)
	else
		hair_style			= sanitize_inlist(hair_style, hair_styles_female_list)
		facial_hair_style			= sanitize_inlist(facial_hair_style, facial_hair_styles_female_list)
		underwear		= sanitize_inlist(underwear, underwear_f)
		undershirt		= sanitize_inlist(undershirt, undershirt_f)
		socks			= sanitize_inlist(socks, socks_f)

	age				= sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
	hair_color			= sanitize_hexcolor(hair_color, 3, 0)
	facial_hair_color			= sanitize_hexcolor(facial_hair_color, 3, 0)
	eye_color		= sanitize_hexcolor(eye_color, 3, 0)
	skin_tone		= sanitize_inlist(skin_tone, skin_tones)
	backbag			= sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
	mutant_color	= sanitize_hexcolor(mutant_color, 3, 0)

	userandomjob	= sanitize_integer(userandomjob, 0, 1, initial(userandomjob))
	job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
	job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
	job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
	job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
	job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
	job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
	job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
	job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
	job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))

	return 1

/datum/preferences/proc/save_character()
	if(!path)				return 0
	var/savefile/S = new /savefile(path)
	if(!S)					return 0
	S.cd = "/character[default_slot]"

	S["version"]			<< SAVEFILE_VERSION_MAX	//load_character will sanitize any bad data, so assume up-to-date.

	//Character
	S["OOC_Notes"]			<< metadata
	S["real_name"]			<< real_name
	S["name_is_always_random"] << be_random_name
	S["body_is_always_random"] << be_random_body
	S["gender"]				<< gender
	S["age"]				<< age
	S["hair_color"]			<< hair_color
	S["facial_hair_color"]	<< facial_hair_color
	S["eye_color"]			<< eye_color
	S["skin_tone"]			<< skin_tone
	S["hair_style_name"]	<< hair_style
	S["facial_style_name"]	<< facial_hair_style
	S["underwear"]			<< underwear
	S["undershirt"]			<< undershirt
	S["socks"]				<< socks
	S["backbag"]			<< backbag
	S["species"]			<< pref_species.name
	S["mutant_color"]		<< mutant_color

	//Jobs
	S["userandomjob"]		<< userandomjob
	S["job_civilian_high"]	<< job_civilian_high
	S["job_civilian_med"]	<< job_civilian_med
	S["job_civilian_low"]	<< job_civilian_low
	S["job_medsci_high"]	<< job_medsci_high
	S["job_medsci_med"]		<< job_medsci_med
	S["job_medsci_low"]		<< job_medsci_low
	S["job_engsec_high"]	<< job_engsec_high
	S["job_engsec_med"]		<< job_engsec_med
	S["job_engsec_low"]		<< job_engsec_low

	return 1

#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
/*
//DEBUG
//Some crude tools for testing savefiles
//path is the savefile path
/client/verb/savefile_export(path as text)
	var/savefile/S = new /savefile(path)
	S.ExportText("/",file("[path].txt"))
//path is the savefile path
/client/verb/savefile_import(path as text)
	var/savefile/S = new /savefile(path)
	S.ImportText("/",file("[path].txt"))
*/

license: mit


code:
//toggles
/client/verb/toggle_ghost_ears()
	set name = "Show/Hide GhostEars"
	set category = "Preferences"
	set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
	prefs.chat_toggles ^= CHAT_GHOSTEARS
	src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"]."
	prefs.save_preferences()
	feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/toggle_ghost_sight()
	set name = "Show/Hide GhostSight"
	set category = "Preferences"
	set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
	prefs.chat_toggles ^= CHAT_GHOSTSIGHT
	src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"]."
	prefs.save_preferences()
	feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/toggle_ghost_whispers()
	set name = "Show/Hide GhostWhispers"
	set category = "Preferences"
	set desc = ".Toggle between hearing all whispers, and only whispers of nearby mobs"
	prefs.chat_toggles ^= CHAT_GHOSTWHISPER
	src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"]."
	prefs.save_preferences()
	feedback_add_details("admin_verb","TGW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/toggle_ghost_radio()
	set name = "Show/Hide GhostRadio"
	set category = "Preferences"
	set desc = ".Enable or disable hearing radio chatter as a ghost"
	prefs.chat_toggles ^= CHAT_GHOSTRADIO
	src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"]."
	prefs.save_preferences()
	feedback_add_details("admin_verb","TGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1

/client/verb/toggle_ghost_pda()
	set name = "Show/Hide GhostPDA"
	set category = "Preferences"
	set desc = ".Toggle Between seeing all mob pda messages, and only pda messages of nearby mobs"
	prefs.chat_toggles ^= CHAT_GHOSTPDA
	src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"]."
	prefs.save_preferences()
	feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/proc/toggle_hear_radio()
	set name = "Show/Hide RadioChatter"
	set category = "Preferences"
	set desc = "Toggle seeing radiochatter from nearby radios and speakers"
	if(!holder) return
	prefs.chat_toggles ^= CHAT_RADIO
	prefs.save_preferences()
	usr << "You will [(prefs.chat_toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers"
	feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/proc/toggleadminhelpsound()
	set name = "Hear/Silence Adminhelps"
	set category = "Preferences"
	set desc = "Toggle hearing a notification when admin PMs are recieved"
	if(!holder)	return
	prefs.toggles ^= SOUND_ADMINHELP
	prefs.save_preferences()
	usr << "You will [(prefs.toggles & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive."
	feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/proc/deadchat()
	set name = "Show/Hide Deadchat"
	set category = "Preferences"
	set desc ="Toggles seeing deadchat"
	prefs.chat_toggles ^= CHAT_DEAD
	prefs.save_preferences()
	src << "You will [(prefs.chat_toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat."
	feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/proc/toggleprayers()
	set name = "Show/Hide Prayers"
	set category = "Preferences"
	set desc = "Toggles seeing prayers"
	prefs.chat_toggles ^= CHAT_PRAYER
	prefs.save_preferences()
	src << "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat."
	feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/togglePRs()
	set name = "Show/Hide Pull Request Announcements"
	set category = "Preferences"
	set desc = "Toggles receiving a notification when new pull requests are created."
	prefs.chat_toggles ^= CHAT_PULLR
	prefs.save_preferences()
	src << "You will [(prefs.chat_toggles & CHAT_PULLR) ? "now" : "no longer"] see new pull request announcements."
	feedback_add_details("admin_verb","TPullR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/togglemidroundantag()
	set name = "Toggle Midround Antagonist"
	set category = "Preferences"
	set desc = "Toggles whether or not you will be considered for antagonist status given during a round."
	prefs.toggles ^= MIDROUND_ANTAG
	prefs.save_preferences()
	src << "You will [(prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions."
	feedback_add_details("admin_verb","TMidroundA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/toggletitlemusic()
	set name = "Hear/Silence LobbyMusic"
	set category = "Preferences"
	set desc = "Toggles hearing the GameLobby music"
	prefs.toggles ^= SOUND_LOBBY
	prefs.save_preferences()
	if(prefs.toggles & SOUND_LOBBY)
		src << "You will now hear music in the game lobby."
		if(istype(mob, /mob/new_player))
			playtitlemusic()
	else
		src << "You will no longer hear music in the game lobby."
		if(istype(mob, /mob/new_player))
			src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jamsz
	feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/togglemidis()
	set name = "Hear/Silence Midis"
	set category = "Preferences"
	set desc = "Toggles hearing sounds uploaded by admins"
	prefs.toggles ^= SOUND_MIDI
	prefs.save_preferences()
	if(prefs.toggles & SOUND_MIDI)
		src << "You will now hear any sounds uploaded by admins."
		if(admin_sound)
			src << admin_sound
	else
		src << "You will no longer hear sounds uploaded by admins; any currently playing midis have been disabled."
		if(admin_sound && !(admin_sound.status & SOUND_PAUSED))
			admin_sound.status |= SOUND_PAUSED
			src << admin_sound
			admin_sound.status ^= SOUND_PAUSED
	feedback_add_details("admin_verb","TMidi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/listen_ooc()
	set name = "Show/Hide OOC"
	set category = "Preferences"
	set desc = "Toggles seeing OutOfCharacter chat"
	prefs.chat_toggles ^= CHAT_OOC
	prefs.save_preferences()
	src << "You will [(prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel."
	feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful
	set name = "Hear/Silence Ambience"
	set category = "Preferences"
	set desc = "Toggles hearing ambient sound effects"
	prefs.toggles ^= SOUND_AMBIENCE
	prefs.save_preferences()
	if(prefs.toggles & SOUND_AMBIENCE)
		src << "You will now hear ambient sounds."
	else
		src << "You will no longer hear ambient sounds."
		src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
		src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
	feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

//be special
/client/verb/toggle_be_special(role in be_special_flags)
	set name = "Toggle SpecialRole Candidacy"
	set category = "Preferences"
	set desc = "Toggles which special roles you would like to be a candidate for, during events."
	var/role_flag = be_special_flags[role]
	if(!role_flag)	return
	prefs.be_special ^= role_flag
	prefs.save_preferences()
	src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
	feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/verb/toggle_member_publicity()
	set name = "Toggle Membership Publicity"
	set category = "Preferences"
	set desc = "Toggles whether other players can see that you are a BYOND member (OOC blag icon/colours)."
	prefs.toggles ^= MEMBER_PUBLIC
	prefs.save_preferences()
	src << "Others can[(prefs.toggles & MEMBER_PUBLIC) ? "" : "not"] see whether you are a byond member."

var/list/ghost_forms = list("ghost","ghostking","ghostian2","skeleghost","ghost_red","ghost_black", \
							"ghost_blue","ghost_yellow","ghost_green","ghost_pink", \
							"ghost_cyan","ghost_dblue","ghost_dred","ghost_dgreen", \
							"ghost_dcyan","ghost_grey","ghost_dyellow","ghost_dpink")
/client/verb/pick_form()
	set name = "Choose Ghost Form"
	set category = "Preferences"
	set desc = "Choose your preferred ghostly appearance."
//	if(!is_content_unlocked())	return
	var/new_form = input(src, "Choose your ghostly form:","Ghost form chooser",null) as null|anything in ghost_forms
	if(new_form)
		prefs.ghost_form = new_form
		prefs.save_preferences()
		if(istype(mob,/mob/dead/observer))
			mob.icon_state = new_form

/client/verb/toggle_intent_style()
	set name = "Toggle Intent Selection Style"
	set category = "Preferences"
	set desc = "Toggle between directly clicking the desired intent or clicking to rotate through."
	prefs.toggles ^= INTENT_STYLE
	src << "[(prefs.toggles & INTENT_STYLE) ? "Clicking directly on intents selects them." : "Clicking on intents rotates selection clockwise."]"
	prefs.save_preferences()
	feedback_add_details("admin_verb","ITENTS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!


code:
/obj/item/clothing
	name = "clothing"
	var/flash_protect = 0		//Malk: What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
	var/tint = 0				//Malk: Sets the item's level of visual impairment tint, normally set to the same as flash_protect
	var/up = 0					//	   but seperated to allow items to protect but not impair vision, like space helmets
	var/visor_flags = 0			// flags that are added/removed when an item is adjusted up/down
	var/visor_flags_inv = 0		// same as visor_flags, but for flags_inv
	lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi'
	righthand_file = 'icons/mob/inhands/clothing_righthand.dmi'
	var/alt_desc = null

//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
	name = "ears"
	w_class = 1.0
	throwforce = 0
	slot_flags = SLOT_EARS

/obj/item/clothing/ears/earmuffs
	name = "earmuffs"
	desc = "Protects your hearing from loud noises, and quiet ones as well."
	icon_state = "earmuffs"
	item_state = "earmuffs"
	flags = EARBANGPROTECT
	strip_delay = 15
	put_on_delay = 25

//Glasses
/obj/item/clothing/glasses
	name = "glasses"
	icon = 'icons/obj/clothing/glasses.dmi'
	w_class = 2.0
	flags = GLASSESCOVERSEYES
	slot_flags = SLOT_EYES
	var/vision_flags = 0
	var/darkness_view = 2//Base human is 2
	var/invis_view = SEE_INVISIBLE_LIVING
	var/emagged = 0
	var/list/icon/current = list() //the current hud icons
	strip_delay = 20
	put_on_delay = 25

/*
SEE_SELF  // can see self, no matter what
SEE_MOBS  // can see all mobs, no matter what
SEE_OBJS  // can see all objs, no matter what
SEE_TURFS // can see all turfs (and areas), no matter what
SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are
          // in a lit area (via pixel_x,y or smooth movement), can see those pixels
BLIND     // can't see anything
*/

//Gloves
/obj/item/clothing/gloves
	name = "gloves"
	gender = PLURAL //Carn: for grammarically correct text-parsing
	w_class = 2.0
	icon = 'icons/obj/clothing/gloves.dmi'
	siemens_coefficient = 0.50
	body_parts_covered = HANDS
	slot_flags = SLOT_GLOVES
	attack_verb = list("challenged")
	var/transfer_prints = FALSE
	strip_delay = 20
	put_on_delay = 40

// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/proc/Touch(var/atom/A, var/proximity)
	return 0 // return 1 to cancel attack_hand()

//Head
/obj/item/clothing/head
	name = "head"
	icon = 'icons/obj/clothing/hats.dmi'
	body_parts_covered = HEAD
	slot_flags = SLOT_HEAD
	var/blockTracking = 0 //For AI tracking

//Mask
/obj/item/clothing/mask
	name = "mask"
	icon = 'icons/obj/clothing/masks.dmi'
	body_parts_covered = HEAD
	slot_flags = SLOT_MASK
	var/alloweat = 0
	strip_delay = 40
	put_on_delay = 40
	var/mask_adjusted = 0
	var/ignore_maskadjust = 1
	var/adjusted_flags = null

//Override this to modify speech like luchador masks.
/obj/item/clothing/mask/proc/speechModification(message)
	return message

//Proc that moves gas/breath masks out of the way, disabling them and allowing pill/food consumption
/obj/item/clothing/mask/proc/adjustmask(var/mob/user)
	if(!ignore_maskadjust)
		if(!user.canmove || user.stat || user.restrained())
			return
		if(src.mask_adjusted == 1)
			src.icon_state = initial(icon_state)
			gas_transfer_coefficient = initial(gas_transfer_coefficient)
			permeability_coefficient = initial(permeability_coefficient)
			flags |= visor_flags
			flags_inv |= visor_flags_inv
			user << "You push \the [src] back into place."
			src.mask_adjusted = 0
			slot_flags = initial(slot_flags)
		else
			src.icon_state += "_up"
			user << "You push \the [src] out of the way."
			gas_transfer_coefficient = null
			permeability_coefficient = null
			flags &= ~visor_flags
			flags_inv &= ~visor_flags_inv
			src.mask_adjusted = 1
			if(adjusted_flags)
				slot_flags = adjusted_flags
		usr.update_inv_wear_mask()

//Shoes
/obj/item/clothing/shoes
	name = "shoes"
	icon = 'icons/obj/clothing/shoes.dmi'
	desc = "Comfortable-looking shoes."
	gender = PLURAL //Carn: for grammarically correct text-parsing
	var/chained = 0

	body_parts_covered = FEET
	slot_flags = SLOT_FEET

	permeability_coefficient = 0.50
	slowdown = SHOES_SLOWDOWN

/obj/item/proc/negates_gravity()
	return 0

//Suit
/obj/item/clothing/suit
	icon = 'icons/obj/clothing/suits.dmi'
	name = "suit"
	var/fire_resist = T0C+100
	allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen)
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
	slot_flags = SLOT_OCLOTHING
	var/blood_overlay_type = "suit"
	var/togglename = null

//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
//      Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
	name = "space helmet"
	icon_state = "spaceold"
	desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays."
	flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
	item_state = "spaceold"
	permeability_coefficient = 0.01
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
	flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
	cold_protection = HEAD
	min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
	heat_protection = HEAD
	max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
	flash_protect = 2
	strip_delay = 50
	put_on_delay = 50

/obj/item/clothing/suit/space
	name = "space suit"
	desc = "A suit that protects against low pressure environments. Has a big 13 on the back."
	icon_state = "spaceold"
	item_state = "s_suit"
	w_class = 4//bulky item
	gas_transfer_coefficient = 0.01
	permeability_coefficient = 0.02
	flags = STOPSPRESSUREDMAGE | THICKMATERIAL
	body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
	allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals)
	slowdown = 2
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
	flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
	cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
	min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
	heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
	max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
	strip_delay = 80
	put_on_delay = 80

//Under clothing
/obj/item/clothing/under
	icon = 'icons/obj/clothing/uniforms.dmi'
	name = "under"
	body_parts_covered = CHEST|GROIN|LEGS|ARMS
	permeability_coefficient = 0.90
	slot_flags = SLOT_ICLOTHING
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
	var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women
	var/has_sensor = 1//For the crew computer 2 = unable to change mode
	var/sensor_mode = 0
	var/can_adjust = 1
	var/adjusted = 0
	var/suit_color = null

		/*
		1 = Report living/dead
		2 = Report detailed damages
		3 = Report location
		*/
	var/obj/item/clothing/tie/hastie = null

/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
	attachTie(I, user)
	..()

/obj/item/clothing/under/proc/attachTie(obj/item/I, mob/user, notifyAttach = 1)
	if(istype(I, /obj/item/clothing/tie))
		if(hastie)
			if(user)
				user << "[src] already has an accessory."
			return 0
		else
			if(user)
				user.drop_item()
			hastie = I
			I.loc = src
			if(user && notifyAttach)
				user << "You attach [I] to [src]."
			I.transform *= 0.5	//halve the size so it doesn't overpower the under
			I.pixel_x += 8
			I.pixel_y -= 8
			I.layer = FLOAT_LAYER
			overlays += I

			if(istype(loc, /mob/living/carbon/human))
				var/mob/living/carbon/human/H = loc
				H.update_inv_w_uniform(0)

			return 1

/obj/item/clothing/under/examine(mob/user)
	..()
	switch(src.sensor_mode)
		if(0)
			user << "Its sensors appear to be disabled."
		if(1)
			user << "Its binary life sensors appear to be enabled."
		if(2)
			user << "Its vital tracker appears to be enabled."
		if(3)
			user << "Its vital tracker and tracking beacon appear to be enabled."
	if(hastie)
		user << "\A [hastie] is attached to it."

atom/proc/generate_female_clothing(index,t_color,icon,type)
	var/icon/female_clothing_icon	= icon("icon"=icon, "icon_state"="[t_color]_s")
	var/icon/female_s				= icon("icon"='icons/mob/uniform.dmi', "icon_state"="[(type == FEMALE_UNIFORM_FULL) ? "female_full" : "female_top"]")
	female_clothing_icon.Blend(female_s, ICON_MULTIPLY)
	female_clothing_icon 			= fcopy_rsc(female_clothing_icon)
	female_clothing_icons[index] = female_clothing_icon

/obj/item/clothing/under/verb/toggle()
	set name = "Adjust Suit Sensors"
	set category = "Object"
	set src in usr
	var/mob/M = usr
	if (istype(M, /mob/dead/))
		return
	if (!can_use(M))
		return
	if(src.has_sensor >= 2)
		usr << "The controls are locked."
		return 0
	if(src.has_sensor <= 0)
		usr << "This suit does not have any sensors."
		return 0

	var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon")
	var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
	if(get_dist(usr, src) > 1)
		usr << "You have moved too far away."
		return
	sensor_mode = modes.Find(switchMode) - 1

	if (src.loc == usr)
		switch(sensor_mode)
			if(0)
				usr << "You disable your suit's remote sensing equipment."
			if(1)
				usr << "Your suit will now only report whether you are alive or dead."
			if(2)
				usr << "Your suit will now only report your exact vital lifesigns."
			if(3)
				usr << "Your suit will now report your exact vital lifesigns as well as your coordinate position."

	if(istype(loc,/mob/living/carbon/human))
		var/mob/living/carbon/human/H = loc
		if(H.w_uniform == src)
			H.update_suit_sensors()

	..()

/obj/item/clothing/under/AltClick(var/mob/user)
	..()
	if(!user.canUseTopic(user))
		user << "You can't do that right now!"
		return
	if(!in_range(src, user))
		return
	else
		rolldown()

/obj/item/clothing/under/verb/jumpsuit_adjust()
	set name = "Adjust Jumpsuit Style"
	set category = null
	set src in usr
	rolldown()

/obj/item/clothing/under/proc/rolldown()
	if(!can_use(usr))
		return
	if(!can_adjust)
		usr << "You cannot wear this suit any differently."
		return
	if(src.adjusted == 1)
		src.fitted = initial(fitted)
		src.item_color = initial(item_color)
		src.item_color = src.suit_color //colored jumpsuits are shit and break without this
		usr << "You adjust the suit back to normal."
		src.adjusted = 0
	else
		src.fitted = NO_FEMALE_UNIFORM
		src.item_color += "_d"
		usr << "You adjust the suit to wear it more casually."
		src.adjusted = 1
	usr.update_inv_w_uniform()
	..()

/obj/item/clothing/under/examine(mob/user)
	..()
	if(src.adjusted)
		user << "Alt-click on [src] to wear it normally."
	else
		user << "Alt-click on [src] to wear it casually."

/obj/item/clothing/under/verb/removetie()
	set name = "Remove Accessory"
	set category = "Object"
	set src in usr
	if(!istype(usr, /mob/living))
		return
	if(!can_use(usr))
		return

	if(hastie)
		hastie.transform *= 2
		hastie.pixel_x -= 8
		hastie.pixel_y += 8
		hastie.layer = initial(hastie.layer)
		overlays = null
		usr.put_in_hands(hastie)
		hastie = null

		if(istype(loc, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = loc
			H.update_inv_w_uniform(0)

/obj/item/clothing/under/New()
	sensor_mode = pick(0,1,2,3)
	adjusted = 0
	suit_color = item_color
	..()

/obj/item/clothing/proc/weldingvisortoggle()			//Malk: proc to toggle welding visors on helmets, masks, goggles, etc.
	if(can_use(usr))
		if(up)
			up = !up
			flags |= (visor_flags)
			flags_inv |= (visor_flags_inv)
			icon_state = initial(icon_state)
			usr << "You pull \the [src] down."
			flash_protect = initial(flash_protect)
			tint = initial(tint)
		else
			up = !up
			flags &= ~(visor_flags)
			flags_inv &= ~(visor_flags_inv)
			icon_state = "[initial(icon_state)]up"
			usr << "You push \the [src] up."
			flash_protect = 0
			tint = 0

	if(istype(src, /obj/item/clothing/head))			//makes the mob-overlays update
		usr.update_inv_head(0)
	if(istype(src, /obj/item/clothing/glasses))
		usr.update_inv_glasses(0)
	if(istype(src, /obj/item/clothing/mask))
		usr.update_inv_wear_mask(0)

/obj/item/clothing/proc/can_use(mob/user)
	if(user && ismob(user))
		if(!user.stat && user.canmove && !user.restrained())
			return 1
	return 0


code:
//Engineering Mesons

/obj/item/clothing/glasses/meson/engine
	name = "Engineering Scanner Goggles"
	desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes."
	icon_state = "trayson-meson"
	var/mode = 0	//0 - regular mesons mode	1 - t-ray mode
	var/invis_objects = list()
	action_button_name = "Change Scanning Mode"

/obj/item/clothing/glasses/meson/engine/attack_self()
	ui_action_click()

/obj/item/clothing/glasses/meson/engine/ui_action_click()
	mode = !mode

	if(mode)
		SSobj.processing |= src
		vision_flags = 0
		darkness_view = 2
		invis_view = SEE_INVISIBLE_LIVING
		usr << "You toggle the goggles scanning mode to \[T-Ray]."
	else
		SSobj.processing.Remove(src)
		vision_flags = SEE_TURFS
		darkness_view = 1
		invis_view = SEE_INVISIBLE_MINIMUM
		usr << "You toggle the goggles scanning mode to \[Meson]."
		invis_update()

	update_icon()

/obj/item/clothing/glasses/meson/engine/process()
	if(!mode)
		return null

	if(!istype(loc,/mob/living/carbon/human))
		invis_update()
		return null

	var/mob/living/carbon/human/user = loc
	if(user.glasses != src)
		invis_update()
		return null

	scan()

/obj/item/clothing/glasses/meson/engine/proc/scan()
	for(var/turf/T in range(1, loc))

		if(!T.intact)
			continue

		for(var/obj/O in T.contents)
			if(O.level != 1)
				continue

			if(O.invisibility == 101)
				O.invisibility = 0
				invis_objects += O

	spawn(5)
		invis_update()

/obj/item/clothing/glasses/meson/engine/proc/invis_update()
	for(var/obj/O in invis_objects)
		if(!t_ray_on() || !(O in range(1, loc)))
			invis_objects -= O
			var/turf/T = O.loc
			if(T && T.intact)
				O.invisibility = 101

/obj/item/clothing/glasses/meson/engine/proc/t_ray_on()
	if(!istype(loc,/mob/living/carbon/human))
		return 0

	var/mob/living/carbon/human/user = loc
	return mode & (user.glasses == src)

/obj/item/clothing/glasses/meson/engine/update_icon()
	icon_state = mode ? "trayson-tray" : "trayson-meson"
	if(istype(loc,/mob/living/carbon/human/))
		var/mob/living/carbon/human/user = loc
		if(user.glasses == src)
			user.update_inv_glasses()


code:
/obj/item/clothing/glasses/meson
	name = "Optical Meson Scanner"
	desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
	icon_state = "meson"
	item_state = "meson"
	origin_tech = "magnets=2;engineering=2"
	darkness_view = 1
	vision_flags = SEE_TURFS
	invis_view = SEE_INVISIBLE_MINIMUM

/obj/item/clothing/glasses/meson/night
	name = "Night Vision Optical Meson Scanner"
	desc = "An Optical Meson Scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
	icon_state = "nvgmeson"
	item_state = "nvgmeson"
	darkness_view = 8

/obj/item/clothing/glasses/science
	name = "Science Goggles"
	desc = "A pair of snazzy goggles used to protect against chemical spills."
	icon_state = "purple"
	item_state = "glasses"
	unacidable = 1

/obj/item/clothing/glasses/night
	name = "Night Vision Goggles"
	desc = "You can totally see in the dark now!"
	icon_state = "night"
	item_state = "glasses"
	origin_tech = "magnets=4"
	darkness_view = 8
	invis_view = SEE_INVISIBLE_MINIMUM

/obj/item/clothing/glasses/eyepatch
	name = "eyepatch"
	desc = "Yarr."
	icon_state = "eyepatch"
	item_state = "eyepatch"

/obj/item/clothing/glasses/monocle
	name = "monocle"
	desc = "Such a dapper eyepiece!"
	icon_state = "monocle"
	item_state = "headset" // lol

/obj/item/clothing/glasses/material
	name = "Optical Material Scanner"
	desc = "Very confusing glasses."
	icon_state = "material"
	item_state = "glasses"
	origin_tech = "magnets=3;engineering=3"
	vision_flags = SEE_OBJS
	invis_view = SEE_INVISIBLE_MINIMUM

/obj/item/clothing/glasses/regular
	name = "Prescription Glasses"
	desc = "Made by Nerd. Co."
	icon_state = "glasses"
	item_state = "glasses"

/obj/item/clothing/glasses/regular/hipster
	name = "Prescription Glasses"
	desc = "Made by Uncool. Co."
	icon_state = "hipster_glasses"
	item_state = "hipster_glasses"

/obj/item/clothing/glasses/gglasses
	name = "Green Glasses"
	desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme."
	icon_state = "gglasses"
	item_state = "gglasses"

/obj/item/clothing/glasses/sunglasses
	desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes."
	name = "sunglasses"
	icon_state = "sun"
	item_state = "sunglasses"
	darkness_view = 1
	flash_protect = 1
	tint = 1

/obj/item/clothing/glasses/welding
	name = "welding goggles"
	desc = "Protects the eyes from welders; approved by the mad scientist association."
	icon_state = "welding-g"
	item_state = "welding-g"
	action_button_name = "Toggle Welding Goggles"
	flash_protect = 2
	tint = 2
	visor_flags = GLASSESCOVERSEYES
	visor_flags_inv = HIDEEYES

/obj/item/clothing/glasses/welding/attack_self()
	toggle()

/obj/item/clothing/glasses/welding/verb/toggle()
	set category = "Object"
	set name = "Adjust welding goggles"
	set src in usr

	weldingvisortoggle()

/obj/item/clothing/glasses/sunglasses/blindfold
	name = "blindfold"
	desc = "Covers the eyes, preventing sight."
	icon_state = "blindfold"
	item_state = "blindfold"
//	vision_flags = BLIND	//handled in life.dm/handle_regular_hud_updates()
	flash_protect = 2
	tint = 3			// to make them blind

/obj/item/clothing/glasses/sunglasses/big
	desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes."
	icon_state = "bigsunglasses"
	item_state = "bigsunglasses"

/obj/item/clothing/glasses/thermal
	name = "Optical Thermal Scanner"
	desc = "Thermals in the shape of glasses."
	icon_state = "thermal"
	item_state = "glasses"
	origin_tech = "magnets=3"
	vision_flags = SEE_MOBS
	invis_view = 2
	flash_protect = 0

	emp_act(severity)
		if(istype(src.loc, /mob/living/carbon/human))
			var/mob/living/carbon/human/M = src.loc
			M << "The Optical Thermal Scanner overloads and blinds you!"
			if(M.glasses == src)
				M.eye_blind = 3
				M.eye_blurry = 5
				M.disabilities |= NEARSIGHT
				spawn(100)
					M.disabilities &= ~NEARSIGHT
		..()

/obj/item/clothing/glasses/thermal/syndi	//These are now a traitor item, concealed as mesons.	-Pete
	name = "Optical Meson Scanner"
	desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
	icon_state = "meson"
	origin_tech = "magnets=3;syndicate=4"
	flash_protect = -1

/obj/item/clothing/glasses/thermal/monocle
	name = "Thermoncle"
	desc = "A monocle thermal."
	icon_state = "thermoncle"
	flags = null //doesn't protect eyes because it's a monocle, duh

/obj/item/clothing/glasses/thermal/eyepatch
	name = "Optical Thermal Eyepatch"
	desc = "An eyepatch with built-in thermal optics."
	icon_state = "eyepatch"
	item_state = "eyepatch"


code:
/obj/item/clothing/glasses/hud
	name = "HUD"
	desc = "A heads-up display that provides important info in (almost) real time."
	flags = null //doesn't protect eyes because it's a monocle, duh
	origin_tech = "magnets=3;biotech=2"
	var/hud_type = null

/obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot)
	if(slot == slot_glasses)
		var/datum/atom_hud/H = huds[hud_type]
		H.add_hud_to(user)

/obj/item/clothing/glasses/hud/dropped(mob/living/carbon/human/user)
	if(istype(user) && user.glasses == src)
		var/datum/atom_hud/H = huds[hud_type]
		H.remove_hud_from(user)

/obj/item/clothing/glasses/hud/emp_act(severity)
	if(emagged == 0)
		emagged = 1
		desc = desc + " The display flickers slightly."

/obj/item/clothing/glasses/hud/emag_act(mob/user)
	if(emagged == 0)
		emagged = 1
		user << "PZZTTPFFFT"
		desc = desc + " The display flickers slightly."

/obj/item/clothing/glasses/hud/health
	name = "Health Scanner HUD"
	desc = "A heads-up display that scans the humans in view and provides accurate data about their health status."
	icon_state = "healthhud"
	hud_type = DATA_HUD_MEDICAL_ADVANCED

/obj/item/clothing/glasses/hud/health/night
	name = "Night Vision Health Scanner HUD"
	desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness."
	icon_state = "healthhudnight"
	item_state = "glasses"
	darkness_view = 8
	invis_view = SEE_INVISIBLE_MINIMUM

/obj/item/clothing/glasses/hud/security
	name = "Security HUD"
	desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records."
	icon_state = "securityhud"
	hud_type = DATA_HUD_SECURITY_ADVANCED

/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
	name = "Eyepatch HUD"
	desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
	icon_state = "hudpatch"

/obj/item/clothing/glasses/hud/security/sunglasses
	name = "HUDSunglasses"
	desc = "Sunglasses with a HUD."
	icon_state = "sunhud"
	darkness_view = 1
	flash_protect = 1
	tint = 1

/obj/item/clothing/glasses/hud/security/night
	name = "Night Vision Security HUD"
	desc = "An advanced heads-up display which provides id data and vision in complete darkness."
	icon_state = "securityhudnight"
	darkness_view = 8
	invis_view = SEE_INVISIBLE_MINIMUM

/obj/item/clothing/glasses/hud/toggle
	name = "Toggle Hud"
	desc = "A hud with multiple functions."
	action_button_name = "Switch HUD"

/obj/item/clothing/glasses/hud/toggle/attack_self(mob/user)
	if(!ishuman(user))
		return
	var/mob/living/carbon/human/wearer = user
	if (wearer.glasses != src)
		return

	if (hud_type)
		var/datum/atom_hud/H = huds[hud_type]
		H.remove_hud_from(user)

	if (hud_type == DATA_HUD_MEDICAL_ADVANCED)
		hud_type = null
	else if (hud_type == DATA_HUD_SECURITY_ADVANCED)
		hud_type = DATA_HUD_MEDICAL_ADVANCED
	else
		hud_type = DATA_HUD_SECURITY_ADVANCED

	if (hud_type)
		var/datum/atom_hud/H = huds[hud_type]
		H.add_hud_to(user)

/obj/item/clothing/glasses/hud/toggle/thermal
	name = "Thermal HUD Scanner"
	desc = "Thermal imaging HUD in the shape of glasses."
	icon_state = "thermal"
	hud_type = DATA_HUD_SECURITY_ADVANCED
	vision_flags = SEE_MOBS
	invis_view = 2

/obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user)
	..()
	switch (hud_type)
		if (DATA_HUD_MEDICAL_ADVANCED)
			icon_state = "meson"
		if (DATA_HUD_SECURITY_ADVANCED)
			icon_state = "thermal"
		else
			icon_state = "purple"
	user.update_inv_glasses()

/obj/item/clothing/glasses/hud/toggle/thermal/emp_act(severity)
	if(istype(src.loc, /mob/living/carbon/human))
		var/mob/living/carbon/human/M = src.loc
		if(M.glasses == src)
			M << "The [src] overloads and blinds you!"
			M.eye_blind = 3
			M.eye_blurry = 5
			M.disabilities |= NEARSIGHT
			spawn(100)
				M.disabilities &= ~NEARSIGHT
	..()


code:
/obj/item/clothing/gloves/boxing
	name = "boxing gloves"
	desc = "Because you really needed another excuse to punch your crewmates."
	icon_state = "boxing"
	item_state = "boxing"
	put_on_delay = 60
	species_exception = list(/datum/species/golem, /datum/species/golem/adamantine) // now you too can be a golem boxing champion

/obj/item/clothing/gloves/boxing/green
	icon_state = "boxinggreen"
	item_state = "boxinggreen"

/obj/item/clothing/gloves/boxing/blue
	icon_state = "boxingblue"
	item_state = "boxingblue"

/obj/item/clothing/gloves/boxing/yellow
	icon_state = "boxingyellow"
	item_state = "boxingyellow"


code:
/obj/item/clothing/gloves/color/yellow
	desc = "These gloves will protect the wearer from electric shock."
	name = "insulated gloves"
	icon_state = "yellow"
	item_state = "ygloves"
	siemens_coefficient = 0
	permeability_coefficient = 0.05
	item_color="yellow"

/obj/item/clothing/gloves/color/yellow/fake
	desc = "These gloves will protect the wearer from electric shock. They don't feel like rubber..."
	siemens_coefficient = 1

/obj/item/clothing/gloves/color/fyellow                             //Cheap Chinese Crap
	desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
	name = "budget insulated gloves"
	icon_state = "yellow"
	item_state = "ygloves"
	siemens_coefficient = 1			//Set to a default of 1, gets overridden in New()
	permeability_coefficient = 0.05
	item_color="yellow"

/obj/item/clothing/gloves/color/fyellow/New()
	siemens_coefficient = pick(0,0.5,0.5,0.5,0.5,0.75,1.5)

/obj/item/clothing/gloves/color/black
	desc = "These gloves are fire-resistant."
	name = "black gloves"
	icon_state = "black"
	item_state = "bgloves"
	item_color="brown"
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
	heat_protection = HANDS
	max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT

/obj/item/clothing/gloves/color/black/hos
	item_color = "hosred"		//Exists for washing machines. Is not different from black gloves in any way.

/obj/item/clothing/gloves/color/black/ce
	item_color = "chief"			//Exists for washing machines. Is not different from black gloves in any way.

/obj/item/clothing/gloves/color/black/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	if(istype(W, /obj/item/weapon/wirecutters))
		if(icon_state == initial(icon_state)) //only if not dyed
			user << "You snip the fingertips off of [src]."
			playsound(user.loc,'sound/items/Wirecutter.ogg', rand(10,50), 1)
			new /obj/item/clothing/gloves/fingerless(user.loc)
			qdel(src)
	..()

/obj/item/clothing/gloves/color/orange
	name = "orange gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "orange"
	item_state = "orangegloves"
	item_color="orange"

/obj/item/clothing/gloves/color/red
	name = "red gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "red"
	item_state = "redgloves"
	item_color = "red"

/obj/item/clothing/gloves/color/rainbow
	name = "rainbow gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "rainbow"
	item_state = "rainbowgloves"
	item_color = "rainbow"

/obj/item/clothing/gloves/color/rainbow/clown
	item_color = "clown"

/obj/item/clothing/gloves/color/blue
	name = "blue gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "blue"
	item_state = "bluegloves"
	item_color="blue"

/obj/item/clothing/gloves/color/purple
	name = "purple gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "purple"
	item_state = "purplegloves"
	item_color="purple"

/obj/item/clothing/gloves/color/green
	name = "green gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "green"
	item_state = "greengloves"
	item_color="green"

/obj/item/clothing/gloves/color/grey
	name = "grey gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "gray"
	item_state = "graygloves"
	item_color="grey"

/obj/item/clothing/gloves/color/grey/rd
	item_color = "director"			//Exists for washing machines. Is not different from gray gloves in any way.

/obj/item/clothing/gloves/color/grey/hop
	item_color = "hop"				//Exists for washing machines. Is not different from gray gloves in any way.

/obj/item/clothing/gloves/color/light_brown
	name = "light brown gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "lightbrown"
	item_state = "lightbrowngloves"
	item_color="light brown"

/obj/item/clothing/gloves/color/brown
	name = "brown gloves"
	desc = "A pair of gloves, they don't look special in any way."
	icon_state = "brown"
	item_state = "browngloves"
	item_color="brown"

/obj/item/clothing/gloves/color/brown/cargo
	item_color = "cargo"					//Exists for washing machines. Is not different from brown gloves in any way.

/obj/item/clothing/gloves/color/captain
	desc = "Regal blue gloves, with a nice gold trim. Swanky."
	name = "captain's gloves"
	icon_state = "captain"
	item_state = "egloves"
	item_color = "captain"
	siemens_coefficient = 0
	permeability_coefficient = 0.05
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
	heat_protection = HANDS
	max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
	strip_delay = 60

/obj/item/clothing/gloves/color/latex
	name = "latex gloves"
	desc = "Cheap sterile gloves made from latex."
	icon_state = "latex"
	item_state = "lgloves"
	siemens_coefficient = 0.30
	permeability_coefficient = 0.01
	item_color="white"
	transfer_prints = TRUE

/obj/item/clothing/gloves/color/latex/cmo
	item_color = "medical"		//Exists for washing machines. Is not different from latex gloves in any way.

/obj/item/clothing/gloves/color/latex/nitrile
	name = "nitrile gloves"
	desc = "Pricy sterile gloves that are stronger than latex."
	icon_state = "nitrile"
	item_state = "nitrilegloves"
	transfer_prints = FALSE

/obj/item/clothing/gloves/color/white
	name = "white gloves"
	desc = "These look pretty fancy."
	icon_state = "white"
	item_state = "wgloves"
	item_color="mime"

/obj/item/clothing/gloves/color/white/redcoat
	item_color = "redcoat"		//Exists for washing machines. Is not different from white gloves in any way.


code:
/obj/item/clothing/gloves/fingerless
	name = "fingerless gloves"
	desc = "Plain black gloves without fingertips for the hard working."
	icon_state = "fingerless"
	item_state = "fingerless"
	item_color = null	//So they don't wash.
	transfer_prints = TRUE
	strip_delay = 40
	put_on_delay = 20
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT

/obj/item/clothing/gloves/botanic_leather
	name = "botanist's leather gloves"
	desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin.  They're also quite warm."
	icon_state = "leather"
	item_state = "ggloves"
	permeability_coefficient = 0.9
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
	heat_protection = HANDS
	max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT

/obj/item/clothing/gloves/combat
	name = "combat gloves"
	desc = "These tactical gloves are fireproof and shock resistant."
	icon_state = "black"
	item_state = "bgloves"
	siemens_coefficient = 0
	permeability_coefficient = 0.05
	strip_delay = 80
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
	heat_protection = HANDS
	max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT


code:
/*
	Dear ninja gloves

	This isn't because I like you
	this is because your father is a bastard

	...
	I guess you're a little cool.
	 -Sayu
*/

/obj/item/clothing/gloves/space_ninja
	desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
	name = "ninja gloves"
	icon_state = "s-ninja"
	item_state = "s-ninja"
	siemens_coefficient = 0
	cold_protection = HANDS
	min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
	heat_protection = HANDS
	max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
	strip_delay = 120
	var/draining = 0
	var/candrain = 0
	var/mindrain = 200
	var/maxdrain = 400

/*
	This runs the gamut of what ninja gloves can do
	The other option would be a dedicated ninja touch bullshit proc on everything
	which would probably more efficient, but ninjas are pretty rare.
	This was mostly introduced to keep ninja code from contaminating other code;
	with this in place it would be easier to untangle the rest of it.

	For the drain proc, see events/ninja.dm
*/
/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity)
	if(!candrain || draining) return 0

	var/mob/living/carbon/human/H = loc
	if(!istype(H)) return 0 // what
	var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
	if(!istype(suit)) return 0
	if(isturf(A)) return 0

	if(!proximity) // todo: you could add ninja stars or computer hacking here
		return 0

	A.add_fingerprint(H)

	// steal energy from powered things
	if(istype(A,/mob/living/silicon/robot))
		drain("CYBORG",A,suit)
		return 1

	if(istype(A,/obj/machinery/power/apc))
		drain("APC",A,suit)
		return 1

	if(istype(A,/obj/structure/cable))
		drain("WIRE",A,suit)
		return 1

	if(istype(A,/obj/structure/grille))
		var/obj/structure/cable/C = locate() in A.loc
		if(C)
			drain("WIRE",C,suit)
		return 1

	if(istype(A,/obj/machinery/power/smes))
		drain("SMES",A,suit)
		return 1

	if(istype(A,/obj/mecha))
		drain("MECHA",A,suit)
		return 1

	if(istype(A,/obj/machinery/computer/rdconsole)) // download research
		drain("RESEARCH",A,suit)
		return 1

	if(istype(A,/obj/machinery/r_n_d/server))
		A.add_fingerprint(H)
		var/obj/machinery/r_n_d/server/S = A
		if(S.disabled)
			return 1
		if(S.shocked)
			S.shock(H,50)
			return 1
		drain("RESEARCH",A,suit)
		return 1

	//do AI transfers
	if(istype(A,/mob/living/silicon/ai))
		suit.NAI.transfer_ai("AICORE", "AICARD", A, H)
		return 1

	if(istype(A,/obj/structure/AIcore/deactivated))
		suit.NAI.transfer_ai("INACTIVE","AICARD",A, H)
		return 1

	if(istype(A,/obj/machinery/computer/aifixer))
		suit.NAI.transfer_ai("AIFIXER","AICARD",A, H)
		return 1


code:
//Brought back as an adminspawn only item... for now

/obj/item/clothing/gloves/stungloves
	desc = "On closer inspection, these are yellow gloves with some kind of device attached to them..."
	name = "budget insulated gloves"
	icon_state = "yellow"
	item_state = "ygloves"
	siemens_coefficient = 1.5
	item_color = "yellow"
	var/atk_verb = "stunned"
	var/stunforce = 15 //Stun baton stunforce is 21
	var/energyCost = 100
	var/cell_type = /obj/item/weapon/stock_parts/cell //Contains 1000 charge.
	var/obj/item/weapon/stock_parts/cell/power_supply

/obj/item/clothing/gloves/stungloves/New()
	..()
	overlays += "gloves_wire"
	overlays += "gloves_cell"
	if(cell_type)
		power_supply = new cell_type(src)
	else
		return
	power_supply.give(power_supply.maxcharge)

// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/stungloves/Touch(var/atom/A, var/proximity)
	var/mob/living/carbon/human/M = loc
	if(!istype(M)) return 0
	if(proximity && ishuman(A))
		var/mob/living/carbon/human/H = A
		if(H.w_uniform)
			H.w_uniform.add_fingerprint(M) //Unless they're wearing something other than stun gloves the prints won't transfer.
		if(!src.power_supply || src.power_supply.charge >= src.energyCost)
			add_logs(M, H, "stunned", object="stun gloves")
			M.do_attack_animation(H)
			if(src.atk_verb)
				H.visible_message("[M] has [src.atk_verb] [H]!", \
								"[M] has [src.atk_verb] [H]!")
			H.Stun(src.stunforce/2)
			H.Weaken(src.stunforce)
			H.apply_effect(STUTTER, src.stunforce)
			if(src.power_supply)
				src.power_supply.use(src.energyCost)
		else if(src.power_supply.charge < src.energyCost)
			add_logs(M, H, "attempted to stun")
			M << "Out of charge!"
			H.visible_message("[M] has touched [H].", \
							"[M] has touched [H].")
		return 1
	return 0


code:
//Hat Station 13

/obj/item/clothing/head/collectable
	name = "collectable hat"
	desc = "A rare collectable hat."

/obj/item/clothing/head/collectable/petehat
	name = "ultra rare Pete's hat!"
	desc = "It smells faintly of plasma."
	icon_state = "petehat"

/obj/item/clothing/head/collectable/slime
	name = "collectable slime cap!"
	desc = "It just latches right in place!"
	icon_state = "slime"

/obj/item/clothing/head/collectable/xenom
	name = "collectable xenomorph helmet!"
	desc = "Hiss hiss hiss!"
	icon_state = "xenom"

/obj/item/clothing/head/collectable/chef
	name = "collectable chef's hat"
	desc = "A rare chef's hat meant for hat collectors!"
	icon_state = "chef"
	item_state = "chef"

/obj/item/clothing/head/collectable/paper
	name = "collectable paper hat"
	desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Librarians."
	icon_state = "paper"

/obj/item/clothing/head/collectable/tophat
	name = "collectable top hat"
	desc = "A top hat worn by only the most prestigious hat collectors."
	icon_state = "tophat"
	item_state = "that"

/obj/item/clothing/head/collectable/captain
	name = "collectable captain's hat"
	desc = "A collectable hat that'll make you look just like a real comdom!"
	icon_state = "captain"
	item_state = "caphat"

/obj/item/clothing/head/collectable/police
	name = "collectable police officer's hat"
	desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
	icon_state = "policehelm"

/obj/item/clothing/head/collectable/beret
	name = "collectable beret"
	desc = "A collectable red beret. It smells faintly of garlic."
	icon_state = "beret"

/obj/item/clothing/head/collectable/welding
	name = "collectable welding helmet"
	desc = "A collectable welding helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this helmet is done so at the owner's own risk!"
	icon_state = "welding"
	item_state = "welding"

/obj/item/clothing/head/collectable/slime
	name = "collectable slime hat"
	desc = "Just like a real brain slug!"
	icon_state = "headslime"
	item_state = "headslime"

/obj/item/clothing/head/collectable/flatcap
	name = "collectable flat cap"
	desc = "A collectible farmer's flat cap!"
	icon_state = "flat_cap"
	item_state = "detective"

/obj/item/clothing/head/collectable/pirate
	name = "collectable pirate hat"
	desc = "You'd make a great Dread Syndie Roberts!"
	icon_state = "pirate"
	item_state = "pirate"

/obj/item/clothing/head/collectable/kitty
	name = "collectable kitty ears"
	desc = "The fur feels... a bit too realistic."
	icon_state = "kitty"
	item_state = "kitty"

/obj/item/clothing/head/collectable/rabbitears
	name = "collectable rabbit ears"
	desc = "Not as lucky as the feet!"
	icon_state = "bunny"
	item_state = "bunny"

/obj/item/clothing/head/collectable/wizard
	name = "collectable wizard's hat"
	desc = "NOTE: Any magical powers gained from wearing this hat are purely coincidental."
	icon_state = "wizard"

/obj/item/clothing/head/collectable/hardhat
	name = "collectable hard hat"
	desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!"
	icon_state = "hardhat0_yellow"
	item_state = "hardhat0_yellow"

/obj/item/clothing/head/collectable/HoS
	name = "collectable HoS hat"
	desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!"
	icon_state = "hoscap"

/obj/item/clothing/head/collectable/thunderdome
	name = "collectable Thunderdome helmet"
	desc = "Go Red! I mean Green! I mean Red! No Green!"
	icon_state = "thunderdome"
	item_state = "thunderdome"

/obj/item/clothing/head/collectable/swat
	name = "collectable SWAT helmet"
	desc = "That's not real blood. That's red paint." //Reference to the actual description
	icon_state = "swat"
	item_state = "swat"


code:
/obj/item/clothing/head/hardhat
	name = "hard hat"
	desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight."
	icon_state = "hardhat0_yellow"
	item_state = "hardhat0_yellow"
	var/brightness_on = 6 //luminosity when on
	light_power = 2
	var/on = 0
	item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite)
	armor = list(melee = 30, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20)
	flags_inv = 0
	action_button_name = "Toggle Helmet Light"

	attack_self(mob/user)
		if(!isturf(user.loc))
			user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
			return
		on = !on
		icon_state = "hardhat[on]_[item_color]"
		item_state = "hardhat[on]_[item_color]"
		user.update_inv_head()	//so our mob-overlays update

		if(on)	set_light(brightness_on)
		else	set_light(0)

/obj/item/clothing/head/hardhat/orange
	icon_state = "hardhat0_orange"
	item_state = "hardhat0_orange"
	item_color = "orange"

/obj/item/clothing/head/hardhat/red
	icon_state = "hardhat0_red"
	item_state = "hardhat0_red"
	item_color = "red"
	name = "firefighter helmet"
	flags = STOPSPRESSUREDMAGE
	heat_protection = HEAD
	max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
	cold_protection = HEAD
	min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT

/obj/item/clothing/head/hardhat/white
	icon_state = "hardhat0_white"
	item_state = "hardhat0_white"
	item_color = "white"
	flags = STOPSPRESSUREDMAGE
	heat_protection = HEAD
	max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
	cold_protection = HEAD
	min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT

/obj/item/clothing/head/hardhat/dblue
	icon_state = "hardhat0_dblue"
	item_state = "hardhat0_dblue"
	item_color = "dblue"

/obj/item/clothing/head/hardhat/atmos
	icon_state = "hardhat0_atmos"
	item_state = "hardhat0_atmos"
	item_color = "atmos"
	name = "atmospheric technician's firefighting helmet"
	desc = "A firefighter's helmet, able to keep the user cool in any situation."
	flags = STOPSPRESSUREDMAGE
	flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
	heat_protection = HEAD
	max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
	cold_protection = HEAD
	min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT


code:
/obj/item/clothing/head/helmet
	name = "helmet"
	desc = "Standard Security gear. Protects the head from impacts."
	icon_state = "helmet"
	flags = HEADCOVERSEYES | HEADBANGPROTECT
	item_state = "helmet"
	armor = list(melee = 50, bullet = 15, laser = 50,energy = 10, bomb = 25, bio = 0, rad = 0)
	flags_inv = HIDEEARS|HIDEEYES
	cold_protection = HEAD
	min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT
	heat_protection = HEAD
	max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
	strip_delay = 60

/obj/item/clothing/head/helmet/alt
	name = "bulletproof helmet"
	desc = "A bulletproof combat helmet that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent."
	icon_state = "helmetalt"
	item_state = "helmetalt"
	armor = list(melee = 25, bullet = 80, laser = 10, energy = 10, bomb = 40, bio = 0, rad = 0)

/obj/item/clothing/head/helmet/riot
	name = "riot helmet"
	desc = "It's a helmet specifically designed to protect against close range attacks."
	icon_state = "riot"
	item_state = "helmet"
	flags = HEADCOVERSEYES|HEADCOVERSMOUTH|HEADBANGPROTECT
	armor = list(melee = 82, bullet = 15, laser = 5,energy = 5, bomb = 5, bio = 2, rad = 0)
	flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
	strip_delay = 80
	action_button_name = "Toggle Helmet Visor"
	visor_flags = HEADCOVERSEYES|HEADCOVERSMOUTH
	visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE

/obj/item/clothing/head/helmet/riot/attack_self()
	if(usr.canmove && !usr.stat && !usr.restrained())
		if(up)
			up = !up
			flags |= (visor_flags)
			flags_inv |= (visor_flags_inv)
			icon_state = initial(icon_state)
			usr << "You pull \the [src] down."
			usr.update_inv_head(0)
		else
			up = !up
			flags &= ~(visor_flags)
			flags_inv &= ~(visor_flags_inv)
			icon_state = "[initial(icon_state)]up"
			usr << "You push \the [src] up."
			usr.update_inv_head(0)

/obj/item/clothing/head/helmet/swat
	name = "\improper SWAT helmet"
	desc = "An extremely robust, space-worthy helmet with the Nanotrasen logo emblazoned on the top."
	icon_state = "swat"
	item_state = "swat"
	armor = list(melee = 80, bullet = 60, laser = 50,energy = 25, bomb = 50, bio = 10, rad = 0)
	cold_protection = HEAD
	min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
	heat_protection = HEAD
	max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
	strip_delay = 80

/obj/item/clothing/head/helmet/thunderdome
	name = "\improper Thunderdome helmet"
	desc = "<i>'Let the battle commence!'</i>"
	icon_state = "thunderdome"
	item_state = "thunderdome"
	armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0)
	cold_protection = HEAD
	min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
	heat_protection = HEAD
	max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
	strip_delay = 80

/obj/item/clothing/head/helmet/roman
	name = "roman helmet"
	desc = "An ancient helmet made of bronze and leather."
	flags = HEADCOVERSEYES
	armor = list(melee = 25, bullet = 0, laser = 25, energy = 10, bomb = 10, bio = 0, rad = 0)
	icon_state = "roman"
	item_state = "roman"
	strip_delay = 100

/obj/item/clothing/head/helmet/roman/legionaire
	name = "roman legionaire helmet"
	desc = "An ancient helmet made of bronze and leather. Has a red crest on top of it."
	icon_state = "roman_c"
	item_state = "roman_c"

/obj/item/clothing/head/helmet/gladiator
	name = "gladiator helmet"
	desc = "Ave, Imperator, morituri te salutant."
	icon_state = "gladiator"
	flags = HEADCOVERSEYES|BLOCKHAIR
	item_state = "gladiator"
	flags_inv = HIDEMASK|HIDEEARS|HIDEEYES

obj/item/clothing/head/helmet/redtaghelm
	name = "red laser tag helmet"
	desc = "They have chosen their own end."
	icon_state = "redtaghelm"
	flags = HEADCOVERSEYES
	item_state = "redtaghelm"
	armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0)
	// Offer about the same protection as a hardhat.
	flags_inv = HIDEEARS|HIDEEYES

obj/item/clothing/head/helmet/bluetaghelm
	name = "blue laser tag helmet"
	desc = "They'll need more men."
	icon_state = "bluetaghelm"
	flags = HEADCOVERSEYES
	item_state = "bluetaghelm"
	armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0)
	// Offer about the same protection as a hardhat.
	flags_inv = HIDEEARS|HIDEEYES


code:
//Bartender
/obj/item/clothing/head/chefhat
	name = "chef's hat"
	desc = "It's a hat used by chefs to keep hair out of your food. Judging by the food in the mess, they don't work."
	icon_state = "chef"
	item_state = "chef"
	desc = "The commander in chef's head wear."
	strip_delay = 10
	put_on_delay = 10

//Captain
/obj/item/clothing/head/caphat
	name = "captain's hat"
	desc = "It's good being the king."
	icon_state = "captain"
	item_state = "that"
	flags_inv = 0
	armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
	strip_delay = 60

//Captain: This is no longer space-worthy
/obj/item/clothing/head/caphat/parade
	name = "captain's parade cap"
	desc = "Worn only by Captains with an abundance of class."
	icon_state = "capcap"

//Head of Personnel
/obj/item/clothing/head/hopcap
	name = "head of personnel's cap"
	icon_state = "hopcap"
	desc = "The symbol of true bureaucratic micromanagement."
	armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)

//Chaplain
/obj/item/clothing/head/nun_hood
	name = "nun hood"
	desc = "Maximum piety in this star system."
	icon_state = "nun_hood"
	flags = HEADCOVERSEYES|BLOCKHAIR

/obj/item/clothing/head/det_hat
	name = "detective's fedora"
	desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat."
	icon_state = "detective"
	armor = list(melee = 50, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)

//Mime
/obj/item/clothing/head/beret
	name = "beret"
	desc = "A beret, a mime's favorite headwear."
	icon_state = "beret"

//Security

/obj/item/clothing/head/HoS
	name = "head of security cap"
	desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge."
	icon_state = "hoscap"
	armor = list(melee = 80, bullet = 60, laser = 50, energy = 10, bomb = 25, bio = 10, rad = 0)
	strip_delay = 80

/obj/item/clothing/head/HoS/beret
	name = "head of security beret"
	desc = "A robust beret for the Head of Security, for looking stylish while not sacrificing protection."
	icon_state = "hosberetblack"

/obj/item/clothing/head/warden
	name = "warden's police hat"
	desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
	icon_state = "policehelm"
	armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
	strip_delay = 60

/obj/item/clothing/head/beret/sec
	name = "security beret"
	desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficent protection."
	icon_state = "beret_badge"
	armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
	strip_delay = 60

/obj/item/clothing/head/beret/sec/navyhos
	name = "head of security's beret"
	desc = "A special beret with the Head of Security's insignia emblazoned on it. A symbol of excellence, a badge of courage, a mark of distinction."
	icon_state = "hosberet"

/obj/item/clothing/head/beret/sec/navywarden
	name = "warden's beret"
	desc = "A special beret with the Warden's insignia emblazoned on it. For wardens with class."
	icon_state = "wardenberet"
	armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
	strip_delay = 60

/obj/item/clothing/head/beret/sec/navyofficer
	desc = "A special beret with the security insignia emblazoned on it. For officers with class."
	icon_state = "officerberet"