code:
// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)

datum/proc/on_varedit(modified_var) //called whenever a var is edited
	return

/client/proc/debug_variables(datum/D in world)
	set category = "Debug"
	set name = "View Variables"
	//set src in world

	if(!usr.client || !usr.client.holder)
		usr << "You need to be an administrator to access this."
		return

	var/title = ""
	var/body = ""

	if(!D)
		return
	if(istype(D, /atom))
		var/atom/A = D
		title = "[A.name] (\ref[A]) = [A.type]"

		#ifdef VARSICON
		if (A.icon)
			body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0)
		#endif

	var/icon/sprite

	if(istype(D,/atom))
		var/atom/AT = D
		if(AT.icon && AT.icon_state)
			sprite = new /icon(AT.icon, AT.icon_state)
			usr << browse_rsc(sprite, "view_vars_sprite.png")

	title = "[D] (\ref[D]) = [D.type]"

	body += {" "}

	body += ""

	body += "

"

	if(sprite)
		body += "

	"
	else
		body += "

"

	body += "
"

	if(istype(D,/atom))
		var/atom/A = D
		if(isliving(A))
			body += "[D]"
			if(A.dir)
				body += "
<< [dir2text(A.dir)] >>"
			var/mob/living/M = A
			body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]"
			body += {"

			BRUTE:[M.getBruteLoss()]
			FIRE:[M.getFireLoss()]
			TOXIN:[M.getToxLoss()]
			OXY:[M.getOxyLoss()]
			CLONE:[M.getCloneLoss()]
			BRAIN:[M.getBrainLoss()]
			STAMINA:[M.getStaminaLoss()]

			"}
		else
			body += "[D]"
			if(A.dir)
				body += "
<< [dir2text(A.dir)] >>"
	else
		body += "[D]"

	body += "
"

	body += "

"

	var/formatted_type = text("[D.type]")
	if(length(formatted_type) > 25)
		var/middle_point = length(formatted_type) / 2
		var/splitpoint = findtext(formatted_type,"/",middle_point)
		if(splitpoint)
			formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]"
		else
			formatted_type = "Type too long" //No suitable splitpoint (/) found.

	body += "
[formatted_type]"

	if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D)
		body += "
Marked Object"

	body += "
"

	body += "
	"

	body += "
Refresh"

	//if(ismob(D))
	//	body += "
Show player panel

"

	body += {"	<form>
				<select name="file" size="1"
				onchange="loadPage(this.form.elements\[0\])"
				target="_parent._top"
				onmouseclick="this.focus()"
				style="background-color:#ffffff">
			"}

	body += {"	<option value>Select option</option>
				<option value> </option>
			"}

	body += "<option value='?_src_=vars;mark_object=\ref[D]'>Mark Object</option>"
	body += "<option value='?_src_=vars;proc_call=\ref[D]'>Call Proc</option>"
	if(ismob(D))
		body += "<option value='?_src_=vars;mob_player_panel=\ref[D]'>Show player panel</option>"
	if(istype(D, /atom/movable))
		body += "<option value='?_src_=holder;adminplayerobservefollow=\ref[D]'>Follow</option>"
	else
		var/atom/A = D
		if(istype(A))
			body += "<option value='?_src_=holder;adminplayerobservecoodjump=1;X=[A.x];Y=[A.y];Z=[A.z]'>Jump to</option>"

	body += "<option value>---</option>"

	if(ismob(D))
		body += "<option value='?_src_=vars;give_spell=\ref[D]'>Give Spell</option>"
		body += "<option value='?_src_=vars;give_disease=\ref[D]'>Give Disease</option>"
		body += "<option value='?_src_=vars;ninja=\ref[D]'>Make Space Ninja</option>"
		body += "<option value='?_src_=vars;godmode=\ref[D]'>Toggle Godmode</option>"
		body += "<option value='?_src_=vars;build_mode=\ref[D]'>Toggle Build Mode</option>"
		body += "<option value='?_src_=vars;direct_control=\ref[D]'>Assume Direct Control</option>"
		body += "<option value='?_src_=vars;drop_everything=\ref[D]'>Drop Everything</option>"
		body += "<option value='?_src_=vars;regenerateicons=\ref[D]'>Regenerate Icons</option>"
		body += "<option value='?_src_=vars;offer_control=\ref[D]'>Offer Control to Ghosts</option>"
		if(iscarbon(D))
			body += "<option value>---</option>"
			body += "<option value='?_src_=vars;editorgans=\ref[D]'>Modify organs</option>"
			body += "<option value='?_src_=vars;makeai=\ref[D]'>Make AI</option>"
		if(ishuman(D))
			body += "<option value='?_src_=vars;makemonkey=\ref[D]'>Make monkey</option>"
			body += "<option value='?_src_=vars;setspecies=\ref[D]'>Set Species</option>"
			body += "<option value='?_src_=vars;makerobot=\ref[D]'>Make cyborg</option>"
			body += "<option value='?_src_=vars;makealien=\ref[D]'>Make alien</option>"
			body += "<option value='?_src_=vars;makeslime=\ref[D]'>Make slime</option>"
			body += "<option value='?_src_=vars;purrbation=\ref[D]'>Toggle Purrbation</option>"
		body += "<option value>---</option>"
		body += "<option value='?_src_=vars;gib=\ref[D]'>Gib</option>"
	if(isobj(D))
		body += "<option value='?_src_=vars;delall=\ref[D]'>Delete all of type</option>"
	if(isobj(D) || ismob(D) || isturf(D))
		body += "<option value='?_src_=vars;addreagent=\ref[D]'>Add reagent</option>"
		body += "<option value='?_src_=vars;explode=\ref[D]'>Trigger explosion</option>"
		body += "<option value='?_src_=vars;emp=\ref[D]'>Trigger EM pulse</option>"

	body += "</select></form>"

	body += "

"

	body += "E - Edit, tries to determine the variable type by itself.
"
	body += "C - Change, asks you for the var type first.
"
	body += "M - Mass modify: changes this variable for all objects of this type.
"

	body += "

Search:
	<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>

"

	body += "
"

	var/list/names = list()
	for (var/V in D.vars)
		names += V

	names = sortList(names)

	for (var/V in names)
		body += debug_variable(V, D.vars[V], 0, D)

	body += "
"

	var/html = ""
	if (title)
		html += "<title>[title]</title>"
	html += {""}
	html += ""
	html += body

	html += {"

	"}

	html += ""

	usr << browse(html, "window=variables\ref[D];size=475x650")

	return

/client/proc/debug_variable(name, value, level, datum/DA = null)
	var/html = ""

	if(DA)
		html += "
(E) (C) (M) "
	else
		html += "
"

	if (isnull(value))
		html += "[name] = null"

	else if (istext(value))
		html += "[name] = \"[html_encode(value)]\""

	else if (isicon(value))
		#ifdef VARSICON
		var/icon/I = new/icon(value)
		var/rnd = rand(1,10000)
		var/rname = "tmp\ref[I][rnd].png"
		usr << browse_rsc(I, rname)
		html += "[name] = ([value]) "
		#else
		html += "[name] = /icon ([value])"
		#endif

/*		else if (istype(value, /image))
		#ifdef VARSICON
		var/rnd = rand(1, 10000)
		var/image/I = value

		src << browse_rsc(I.icon, "tmp\ref[value][rnd].png")
		html += "[name] = "
		#else
		html += "[name] = /image ([value])"
		#endif
*/
	else if (isfile(value))
		html += "[name] = '[value]'"

	else if (istype(value, /datum))
		var/datum/D = value
		html += "[name] \ref[value] = [D.type]"

	else if (istype(value, /client))
		var/client/C = value
		html += "[name] \ref[value] = [C] [C.type]"
//
	else if (istype(value, /list))
		var/list/L = value
		html += "[name] = /list ([L.len])"

		if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500))
			// not sure if this is completely right...
			if(0)   //(L.vars.len > 0)
				html += "
"
				html += "
"
			else
				html += "
"
				var/index = 1
				for (var/entry in L)
					if(istext(entry))
						html += debug_variable(entry, L[entry], level + 1)
					//html += debug_variable("[index]", L[index], level + 1)
					else
						html += debug_variable(index, L[index], level + 1)
					index++
				html += "
"

	else
		html += "[name] = [html_encode(value)]"

	html += "
"

	return html

/client/proc/view_var_Topic(href, href_list, hsrc)
	//This should all be moved over to datum/admins/Topic() or something ~Carn
	if( (usr.client != src) || !src.holder )
		return
	if(href_list["Vars"])
		debug_variables(locate(href_list["Vars"]))

	else if(href_list["datumrefresh"])
		var/datum/DAT = locate(href_list["datumrefresh"])
		if(!DAT) //can't be an istype() because /client etc aren't datums
			return
		src.debug_variables(DAT)

	else if(href_list["mob_player_panel"])
		if(!check_rights(0))
			return

		var/mob/M = locate(href_list["mob_player_panel"])
		if(!istype(M))
			usr << "This can only be used on instances of type /mob"
			return

		src.holder.show_player_panel(M)
		href_list["datumrefresh"] = href_list["mob_player_panel"]

	else if(href_list["godmode"])
		if(!check_rights(R_REJUVINATE))
			return

		var/mob/M = locate(href_list["godmode"])
		if(!istype(M))
			usr << "This can only be used on instances of type /mob"
			return

		src.cmd_admin_godmode(M)
		href_list["datumrefresh"] = href_list["godmode"]

	else if(href_list["mark_object"])
		if(!check_rights(0))
			return

		var/datum/D = locate(href_list["mark_object"])
		if(!istype(D))
			usr << "This can only be done to instances of type /datum"
			return

		src.holder.marked_datum = D
		href_list["datumrefresh"] = href_list["mark_object"]

	else if(href_list["proc_call"])
		if(!check_rights(0))
			return

		var/T = locate(href_list["proc_call"])

		if(T)
			callproc_datum(T)

	else if(href_list["regenerateicons"])
		if(!check_rights(0))
			return

		var/mob/M = locate(href_list["regenerateicons"])
		if(!ismob(M))
			usr << "This can only be done to instances of type /mob"
			return
		M.regenerate_icons()

//Needs +VAREDIT past this point

	else if(check_rights(R_VAREDIT))

	//~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).

		if(href_list["rename"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["rename"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN)
			if( !new_name || !M )
				return

			message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
			M.fully_replace_character_name(M.real_name,new_name)
			href_list["datumrefresh"] = href_list["rename"]

		else if(href_list["varnameedit"] && href_list["datumedit"])
			if(!check_rights(0))
				return

			var/D = locate(href_list["datumedit"])
			if(!istype(D,/datum) && !istype(D,/client))
				usr << "This can only be used on instances of types /client or /datum"
				return

			modify_variables(D, href_list["varnameedit"], 1)

		else if(href_list["varnamechange"] && href_list["datumchange"])
			if(!check_rights(0))
				return

			var/D = locate(href_list["datumchange"])
			if(!istype(D,/datum) && !istype(D,/client))
				usr << "This can only be used on instances of types /client or /datum"
				return

			modify_variables(D, href_list["varnamechange"], 0)

		else if(href_list["varnamemass"] && href_list["datummass"])
			if(!check_rights(0))
				return

			var/atom/A = locate(href_list["datummass"])
			if(!istype(A))
				usr << "This can only be used on instances of type /atom"
				return

			cmd_mass_modify_object_variables(A, href_list["varnamemass"])

		else if(href_list["give_spell"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["give_spell"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			src.give_spell(M)
			href_list["datumrefresh"] = href_list["give_spell"]

		else if(href_list["give_disease"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["give_disease"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			src.give_disease(M)
			href_list["datumrefresh"] = href_list["give_spell"]

		else if(href_list["ninja"])
			if(!check_rights(R_FUN))
				return

			var/mob/M = locate(href_list["ninja"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			src.cmd_admin_ninjafy(M)
			href_list["datumrefresh"] = href_list["ninja"]

		else if(href_list["gib"])
			if(!check_rights(R_FUN))
				return

			var/mob/M = locate(href_list["gib"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			src.cmd_admin_gib(M)

		else if(href_list["build_mode"])
			if(!check_rights(R_BUILDMODE))
				return

			var/mob/M = locate(href_list["build_mode"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			togglebuildmode(M)
			href_list["datumrefresh"] = href_list["build_mode"]

		else if(href_list["drop_everything"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["drop_everything"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			if(usr.client)
				usr.client.cmd_admin_drop_everything(M)

		else if(href_list["direct_control"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["direct_control"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return

			if(usr.client)
				usr.client.cmd_assume_direct_control(M)

		else if(href_list["offer_control"])
			if(!check_rights(0))
				return

			var/mob/M = locate(href_list["offer_control"])
			if(!istype(M))
				usr << "This can only be used on instances of type /mob"
				return
			M << "Control of your mob has been offered to dead players."
			log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
			message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts")
			var/poll_message = "Do you want to play as [M.real_name]?"
			if(M.mind && M.mind.assigned_role)
				poll_message = "[poll_message] Job:[M.mind.assigned_role]."
			if(M.mind && M.mind.special_role)
				poll_message = "[poll_message] Status:[M.mind.special_role]."
			var/list/mob/dead/observer/candidates = pollCandidates(poll_message, "pAI", null, FALSE, 100)
			var/mob/dead/observer/theghost = null

			if(candidates.len)
				theghost = pick(candidates)
				M << "Your mob has been taken over by a ghost!"
				message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])")
				M.ghostize(0)
				M.key = theghost.key
			else
				M << "There were no ghosts willing to take control."
				message_admins("No ghosts were willing to take control of [key_name_admin(M)])")

		else if(href_list["delall"])
			if(!check_rights(R_DEBUG|R_SERVER))
				return

			var/obj/O = locate(href_list["delall"])
			if(!isobj(O))
				usr << "This can only be used on instances of type /obj"
				return

			var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
			if(action_type == "Cancel" || !action_type)
				return

			if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes")
				return

			if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
				return

			var/O_type = O.type
			switch(action_type)
				if("Strict type")
					var/i = 0
					for(var/obj/Obj in world)
						if(Obj.type == O_type)
							i++
							qdel(Obj)
						CHECK_TICK
					if(!i)
						usr << "No objects of this type exist"
						return
					log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
					message_admins("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
				if("Type and subtypes")
					var/i = 0
					for(var/obj/Obj in world)
						if(istype(Obj,O_type))
							i++
							qdel(Obj)
						CHECK_TICK
					if(!i)
						usr << "No objects of this type exist"
						return
					log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
					message_admins("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")

		else if(href_list["addreagent"])
			if(!check_rights(0))
				return

			var/atom/A = locate(href_list["addreagent"])

			if(!A.reagents)
				var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num
				if(amount)
					A.create_reagents(amount)

			if(A.reagents)
				var/list/reagent_options = sortList(chemical_reagents_list)
				var/chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") in reagent_options|null
				if(chosen_id)
					var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num
					if(amount)
						A.reagents.add_reagent(chosen_id, amount)
						log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]")
						message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]")

			href_list["datumrefresh"] = href_list["addreagent"]

		else if(href_list["explode"])
			if(!check_rights(R_FUN))
				return

			var/atom/A = locate(href_list["explode"])
			if(!isobj(A) && !ismob(A) && !isturf(A))
				usr << "This can only be done to instances of type /obj, /mob and /turf"
				return

			src.cmd_admin_explosion(A)
			href_list["datumrefresh"] = href_list["explode"]

		else if(href_list["emp"])
			if(!check_rights(R_FUN))
				return

			var/atom/A = locate(href_list["emp"])
			if(!isobj(A) && !ismob(A) && !isturf(A))
				usr << "This can only be done to instances of type /obj, /mob and /turf"
				return

			src.cmd_admin_emp(A)
			href_list["datumrefresh"] = href_list["emp"]

		else if(href_list["rotatedatum"])
			if(!check_rights(0))
				return

			var/atom/A = locate(href_list["rotatedatum"])
			if(!istype(A))
				usr << "This can only be done to instances of type /atom"
				return

			switch(href_list["rotatedir"])
				if("right")
					A.dir = turn(A.dir, -45)
				if("left")
					A.dir = turn(A.dir, 45)
			href_list["datumrefresh"] = href_list["rotatedatum"]

		else if(href_list["editorgans"])
			if(!check_rights(0))
				return

			var/mob/living/carbon/C = locate(href_list["editorgans"])
			if(!istype(C))
				usr << "This can only be done to instances of type /mob/living/carbon"
				return

			manipulate_organs(C)
			href_list["datumrefresh"] = href_list["editorgans"]

		else if(href_list["makehuman"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"])
			if(!istype(Mo))
				usr << "This can only be done to instances of type /mob/living/carbon/monkey"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!Mo)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("humanone"=href_list["makehuman"]))

		else if(href_list["makemonkey"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!H)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))

		else if(href_list["makerobot"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["makerobot"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!H)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("makerobot"=href_list["makerobot"]))

		else if(href_list["makealien"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["makealien"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!H)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("makealien"=href_list["makealien"]))

		else if(href_list["makeslime"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["makeslime"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!H)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("makeslime"=href_list["makeslime"]))

		else if(href_list["makeai"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/H = locate(href_list["makeai"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon"
				return

			if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
				return
			if(!H)
				usr << "Mob doesn't exist anymore"
				return
			holder.Topic(href, list("makeai"=href_list["makeai"]))

		else if(href_list["setspecies"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["setspecies"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			var/result = input(usr, "Please choose a new species","Species") as null|anything in species_list

			if(!H)
				usr << "Mob doesn't exist anymore"
				return

			if(result)
				var/newtype = species_list[result]
				var/datum/species/old_species = H.dna.species
				H.set_species(newtype)
				H.dna.species.admin_set_species(H,old_species)

		else if(href_list["purrbation"])
			if(!check_rights(R_SPAWN))
				return

			var/mob/living/carbon/human/H = locate(href_list["purrbation"])
			if(!istype(H))
				usr << "This can only be done to instances of type /mob/living/carbon/human"
				return

			if(!H)
				usr << "Mob doesn't exist anymore"
				return

			if(H.dna.species.id == "human")
				if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
					usr << "Put [H] on purrbation."
					H << "Something is nya~t right."
					log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.")
					message_admins("[key_name(usr)] has put [key_name(H)] on purrbation.")
					H.dna.features["tail_human"] = "Cat"
					H.dna.features["ears"] = "Cat"
				else
					usr << "Removed [H] from purrbation."
					H << "You are no longer a cat."
					log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.")
					message_admins("[key_name(usr)] has removed [key_name(H)] from purrbation.")
					H.dna.features["tail_human"] = "None"
					H.dna.features["ears"] = "None"
				H.regenerate_icons()
				return

			usr << "You can only put humans on purrbation."

		else if(href_list["adjustDamage"] && href_list["mobToDamage"])
			if(!check_rights(0))
				return

			var/mob/living/L = locate(href_list["mobToDamage"])
			if(!istype(L))
				return

			var/Text = href_list["adjustDamage"]

			var/amount =  input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num

			if(!L)
				usr << "Mob doesn't exist anymore"
				return

			switch(Text)
				if("brute")
					L.adjustBruteLoss(amount)
				if("fire")
					L.adjustFireLoss(amount)
				if("toxin")
					L.adjustToxLoss(amount)
				if("oxygen")
					L.adjustOxyLoss(amount)
				if("brain")
					L.adjustBrainLoss(amount)
				if("clone")
					L.adjustCloneLoss(amount)
				if("stamina")
					L.adjustStaminaLoss(amount)
				else
					usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]"
					return

			if(amount != 0)
				log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
				message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
				href_list["datumrefresh"] = href_list["mobToDamage"]

	return


code:
/mob/proc/HasDisease(datum/disease/D)
	for(var/datum/disease/DD in viruses)
		if(D.IsSame(DD))
			return 1
	return 0

/mob/proc/CanContractDisease(datum/disease/D)
	if(stat == DEAD)
		return 0

	if(D.GetDiseaseID() in resistances)
		return 0

	if(HasDisease(D))
		return 0

	if(!(type in D.viable_mobtypes))
		return 0

	if(count_by_type(viruses, /datum/disease/advance) >= 3)
		return 0

	return 1

/mob/proc/ContractDisease(datum/disease/D)
	if(!CanContractDisease(D))
		return 0
	AddDisease(D)

/mob/proc/AddDisease(datum/disease/D)
	var/datum/disease/DD = new D.type(1, D, 0)
	viruses += DD
	DD.affected_mob = src
	DD.holder = src

	//Copy properties over. This is so edited diseases persist.
	var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
	for(var/V in DD.vars)
		if(V in skipped)
			continue
		if(istype(DD.vars[V],/list))
			var/list/L = D.vars[V]
			DD.vars[V] = L.Copy()
		else
			DD.vars[V] = D.vars[V]

	DD.affected_mob.med_hud_set_status()

/mob/living/carbon/ContractDisease(datum/disease/D)
	if(!CanContractDisease(D))
		return 0

	var/obj/item/clothing/Cl = null
	var/passed = 1

	var/head_ch = 100
	var/body_ch = 100
	var/hands_ch = 25
	var/feet_ch = 25

	if(D.spread_flags & CONTACT_HANDS)
		head_ch = 0
		body_ch = 0
		hands_ch = 100
		feet_ch = 0
	if(D.spread_flags & CONTACT_FEET)
		head_ch = 0
		body_ch = 0
		hands_ch = 0
		feet_ch = 100

	if(prob(15/D.permeability_mod))
		return

	if(satiety>0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease.
		return

	var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)

	if(istype(src, /mob/living/carbon/human))
		var/mob/living/carbon/human/H = src

		switch(target_zone)
			if(1)
				if(isobj(H.head) && !istype(H.head, /obj/item/weapon/paper))
					Cl = H.head
					passed = prob((Cl.permeability_coefficient*100) - 1)
				if(passed && isobj(H.wear_mask))
					Cl = H.wear_mask
					passed = prob((Cl.permeability_coefficient*100) - 1)
			if(2)
				if(isobj(H.wear_suit))
					Cl = H.wear_suit
					passed = prob((Cl.permeability_coefficient*100) - 1)
				if(passed && isobj(slot_w_uniform))
					Cl = slot_w_uniform
					passed = prob((Cl.permeability_coefficient*100) - 1)
			if(3)
				if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS)
					Cl = H.wear_suit
					passed = prob((Cl.permeability_coefficient*100) - 1)

				if(passed && isobj(H.gloves))
					Cl = H.gloves
					passed = prob((Cl.permeability_coefficient*100) - 1)
			if(4)
				if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET)
					Cl = H.wear_suit
					passed = prob((Cl.permeability_coefficient*100) - 1)

				if(passed && isobj(H.shoes))
					Cl = H.shoes
					passed = prob((Cl.permeability_coefficient*100) - 1)

	else if(istype(src, /mob/living/carbon/monkey))
		var/mob/living/carbon/monkey/M = src
		switch(target_zone)
			if(1)
				if(M.wear_mask && isobj(M.wear_mask))
					Cl = M.wear_mask
					passed = prob((Cl.permeability_coefficient*100) - 1)

	if(!passed && (D.spread_flags & AIRBORNE) && !internal)
		passed = (prob((50*D.permeability_mod) - 1))

	if(passed)
		AddDisease(D)

//Same as ContractDisease, except never overidden clothes checks
/mob/proc/ForceContractDisease(datum/disease/D)
	if(!CanContractDisease(D))
		return 0
	AddDisease(D)

/mob/living/carbon/human/CanContractDisease(datum/disease/D)
	if(dna && VIRUSIMMUNE in dna.species.specflags)
		return 0
	return ..()

license: mit


code:
//Visibility Flags
#define HIDDEN_SCANNER	1
#define HIDDEN_PANDEMIC	2

//Disease Flags
#define CURABLE		1
#define CAN_CARRY	2
#define CAN_RESIST	4

//Spread Flags
#define SPECIAL 1
#define NON_CONTAGIOUS 2
#define BLOOD 4
#define CONTACT_FEET 8
#define CONTACT_HANDS 16
#define CONTACT_GENERAL 32
#define AIRBORNE 64

//Severity Defines
#define NONTHREAT	"No threat"
#define MINOR		"Minor"
#define MEDIUM		"Medium"
#define HARMFUL		"Harmful"
#define DANGEROUS 	"Dangerous!"
#define BIOHAZARD	"BIOHAZARD THREAT!"

var/list/diseases = subtypesof(/datum/disease)

/datum/disease
	//Flags
	var/visibility_flags = 0
	var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST
	var/spread_flags = AIRBORNE

	//Fluff
	var/form = "Virus"
	var/name = "No disease"
	var/desc = ""
	var/agent = "some microbes"
	var/spread_text = ""
	var/cure_text = ""

	//Stages
	var/stage = 1
	var/max_stages = 0
	var/stage_prob = 4

	//Other
	var/longevity = 150 //Time in ticks disease stays in objects, Syringes and such are infinite.
	var/list/viable_mobtypes = list() //typepaths of viable mobs
	var/mob/living/carbon/affected_mob = null
	var/atom/movable/holder = null
	var/list/cures = list() //list of cures if the disease has the CURABLE flag, these are reagent ids
	var/infectivity = 65
	var/cure_chance = 8
	var/carrier = 0 //If our host is only a carrier
	var/permeability_mod = 1
	var/severity =	NONTHREAT
	var/list/required_organs = list()
	var/needs_all_cures = TRUE
	var/list/strain_data = list() //dna_spread special bullshit

/datum/disease/proc/stage_act()
	var/cure = has_cure()

	if(carrier && !cure)
		return

	stage = min(stage, max_stages)

	if(!cure)
		if(prob(stage_prob))
			stage = min(stage + 1,max_stages)
	else
		if(prob(cure_chance))
			stage = max(stage - 1, 1)

	if(disease_flags & CURABLE)
		if(cure && prob(cure_chance))
			cure()

/datum/disease/proc/has_cure()
	if(!(disease_flags & CURABLE))
		return 0

	. = cures.len
	for(var/C_id in cures)
		if(!affected_mob.reagents.has_reagent(C_id))
			.--
	if(!. || (needs_all_cures && . < cures.len))
		return 0

/datum/disease/proc/spread(atom/source, force_spread = 0)
	if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
		return

	if(affected_mob)
		if( affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)) )
			return

	var/spread_range = 1

	if(force_spread)
		spread_range = force_spread

	if(spread_flags & AIRBORNE)
		spread_range++

	if(!source)
		if(affected_mob)
			source = affected_mob
		else
			return

	if(isturf(source.loc))
		for(var/mob/living/carbon/C in oview(spread_range, source))
			if(isturf(C.loc))
				if(AStar(source, C.loc,/turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs))
					C.ContractDisease(src)

/datum/disease/process()
	if(!holder)
		SSdisease.processing -= src
		return

	if(prob(infectivity))
		spread(holder)

	if(affected_mob)
		for(var/datum/disease/D in affected_mob.viruses)
			if(D != src)
				if(IsSame(D))
					qdel(D)

		if(holder == affected_mob)
			if(affected_mob.stat != DEAD)
				stage_act()

	if(!affected_mob)
		if(prob(70))
			if(--longevity<=0)
				cure()

/datum/disease/proc/cure()
	if(affected_mob)
		if(disease_flags & CAN_RESIST)
			if(!(type in affected_mob.resistances))
				affected_mob.resistances += type
				remove_virus()
	qdel(src)

/datum/disease/New()
	if(required_organs && required_organs.len)
		if(ishuman(affected_mob))
			var/mob/living/carbon/human/H = affected_mob
			for(var/obj/item/organ/O in required_organs)
				if(!locate(O) in H.organs)
					if(!locate(O) in H.internal_organs)
						cure()
						return

	SSdisease.processing += src

/datum/disease/proc/IsSame(datum/disease/D)
	if(istype(src, D.type))
		return 1
	return 0

/datum/disease/proc/Copy()
	var/datum/disease/D = new type()
	D.strain_data = strain_data.Copy()
	return D

/datum/disease/proc/GetDiseaseID()
	return type

/datum/disease/Destroy()
	SSdisease.processing.Remove(src)
	return ..()

/datum/disease/proc/IsSpreadByTouch()
	if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
		return 1
	return 0

//don't use this proc directly. this should only ever be called by cure()
/datum/disease/proc/remove_virus()
	affected_mob.viruses -= src		//remove the datum from the list
	affected_mob.med_hud_set_status()


code:
/*

	Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties
	which add onto the overall disease.

	If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus.

*/

var/list/archive_diseases = list()

// The order goes from easy to cure to hard to cure.
var/list/advance_cures = 	list(
									"sodiumchloride", "sugar", "orangejuice",
									"spaceacillin", "salglu_solution", "ethanol",
									"leporazine", "synaptizine", "lipolicide",
									"silver", "gold"
								)

/*

	PROPERTIES

 */

/datum/disease/advance

	name = "Unknown" // We will always let our Virologist name our disease.
	desc = "An engineered disease which can contain a multitude of symptoms."
	form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
	agent = "advance microbes"
	max_stages = 5
	spread_text = "Unknown"
	viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)

	// NEW VARS

	var/list/symptoms = list() // The symptoms of the disease.
	var/id = ""
	var/processing = 0

/*

	OLD PROCS

 */

/datum/disease/advance/New(var/process = 1, var/datum/disease/advance/D)

	// Setup our dictionary if it hasn't already.
	if(!dictionary_symptoms.len)
		for(var/symp in list_symptoms)
			var/datum/symptom/S = new symp
			dictionary_symptoms[S.id] = symp

	if(!istype(D))
		D = null
	// Generate symptoms if we weren't given any.

	if(!symptoms || !symptoms.len)

		if(!D || !D.symptoms || !D.symptoms.len)
			symptoms = GenerateSymptoms(0, 2)
		else
			for(var/datum/symptom/S in D.symptoms)
				symptoms += new S.type

	Refresh()
	..(process, D)
	return

/datum/disease/advance/Destroy()
	if(processing)
		for(var/datum/symptom/S in symptoms)
			S.End(src)
	return ..()

// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
	..()
	if(symptoms && symptoms.len)

		if(!processing)
			processing = 1
			for(var/datum/symptom/S in symptoms)
				S.Start(src)

		for(var/datum/symptom/S in symptoms)
			S.Activate(src)
	else
		CRASH("We do not have any symptoms during stage_act()!")

// Compares type then ID.
/datum/disease/advance/IsSame(datum/disease/advance/D)

	if(!(istype(D, /datum/disease/advance)))
		return 0

	if(src.GetDiseaseID() != D.GetDiseaseID())
		return 0
	return 1

// To add special resistances.
/datum/disease/advance/cure(resistance=1)
	if(affected_mob)
		var/id = "[GetDiseaseID()]"
		if(resistance && !(id in affected_mob.resistances))
			affected_mob.resistances[id] = id
		remove_virus()
	qdel(src)	//delete the datum to stop it processing

// Returns the advance disease with a different reference memory.
/datum/disease/advance/Copy(process = 0)
	return new /datum/disease/advance(process, src, 1)

/*

	NEW PROCS

 */

// Mix the symptoms of two diseases (the src and the argument)
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
	if(!(src.IsSame(D)))
		var/list/possible_symptoms = shuffle(D.symptoms)
		for(var/datum/symptom/S in possible_symptoms)
			AddSymptom(new S.type)

/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
	for(var/datum/symptom/symp in symptoms)
		if(symp.id == S.id)
			return 1
	return 0

// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated.
/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0)

	var/list/generated = list() // Symptoms we generated.

	// Generate symptoms. By default, we only choose non-deadly symptoms.
	var/list/possible_symptoms = list()
	for(var/symp in list_symptoms)
		var/datum/symptom/S = new symp
		if(S.level >= level_min && S.level <= level_max)
			if(!HasSymptom(S))
				possible_symptoms += S

	if(!possible_symptoms.len)
		return generated

	// Random chance to get more than one symptom
	var/number_of = amount_get
	if(!amount_get)
		number_of = 1
		while(prob(20))
			number_of += 1

	for(var/i = 1; number_of >= i && possible_symptoms.len; i++)
		generated += pick_n_take(possible_symptoms)

	return generated

/datum/disease/advance/proc/Refresh(new_name = 0)
	//world << "[src.name] \ref[src] - REFRESH!"
	var/list/properties = GenerateProperties()
	AssignProperties(properties)
	id = null

	if(!archive_diseases[GetDiseaseID()])
		if(new_name)
			AssignName()
		archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
		archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)

	var/datum/disease/advance/A = archive_diseases[GetDiseaseID()]
	AssignName(A.name)

//Generate disease properties based on the effects. Returns an associated list.
/datum/disease/advance/proc/GenerateProperties()

	if(!symptoms || !symptoms.len)
		CRASH("We did not have any symptoms before generating properties.")
		return

	var/list/properties = list("resistance" = 1, "stealth" = 1, "stage_rate" = 1, "transmittable" = 1, "severity" = 0)

	for(var/datum/symptom/S in symptoms)

		properties["resistance"] += S.resistance
		properties["stealth"] += S.stealth
		properties["stage_rate"] += S.stage_speed
		properties["transmittable"] += S.transmittable
		properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom

	return properties

// Assign the properties that are in the list.
/datum/disease/advance/proc/AssignProperties(list/properties = list())

	if(properties && properties.len)
		switch(properties["stealth"])
			if(2)
				visibility_flags = HIDDEN_SCANNER
			if(3 to INFINITY)
				visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC

		// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
		SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), BLOOD, AIRBORNE))
		permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1)
		cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20
		stage_prob = max(properties["stage_rate"], 2)
		SetSeverity(properties["severity"])
		GenerateCure(properties)
	else
		CRASH("Our properties were empty or null!")

// Assign the spread type and give it the correct description.
/datum/disease/advance/proc/SetSpread(spread_id)
	switch(spread_id)
		if(NON_CONTAGIOUS)
			spread_text = "None"
		if(SPECIAL)
			spread_text = "None"
		if(CONTACT_GENERAL, CONTACT_HANDS, CONTACT_FEET)
			spread_text = "On contact"
		if(AIRBORNE)
			spread_text = "Airborne"
		if(BLOOD)
			spread_text = "Blood"

	spread_flags = spread_id

/datum/disease/advance/proc/SetSeverity(level_sev)

	switch(level_sev)

		if(-INFINITY to 0)
			severity = NONTHREAT
		if(1)
			severity = MINOR
		if(2)
			severity = MEDIUM
		if(3)
			severity = HARMFUL
		if(4)
			severity = DANGEROUS
		if(5 to INFINITY)
			severity = BIOHAZARD
		else
			severity = "Unknown"

// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure(list/properties = list())
	if(properties && properties.len)
		var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
		//world << "Res = [res]"
		cures = list(advance_cures[res])

		// Get the cure name from the cure_id
		var/datum/reagent/D = chemical_reagents_list[cures[1]]
		cure_text = D.name

	return

// Randomly generate a symptom, has a chance to lose or gain a symptom.
/datum/disease/advance/proc/Evolve(min_level, max_level)
	var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
	if(s)
		AddSymptom(s)
		Refresh(1)
	//check for inert virus to remove it
	for(var/symp in list_symptoms)
		if(istype(symp, /datum/symptom/inert_virus))
			RemoveSymptom(symp)
	return

// Randomly remove a symptom.
/datum/disease/advance/proc/Devolve()
	if(symptoms.len > 1)
		var/s = safepick(symptoms)
		if(s)
			RemoveSymptom(s)
			Refresh(1)
	return

// Name the disease.
/datum/disease/advance/proc/AssignName(name = "Unknown")
	src.name = name
	return

// Return a unique ID of the disease.
/datum/disease/advance/GetDiseaseID()
	if(!id)
		var/list/L = list()
		for(var/datum/symptom/S in symptoms)
			L += S.id
		L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
		var/result = jointext(L, ":")
		id = result
	return id

// Add a symptom, if it is over the limit (with a small chance to be able to go over)
// we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)

	if(HasSymptom(S))
		return

	if(symptoms.len < 5 + rand(-1, 1))
		symptoms += S
	else
		RemoveSymptom(pick(symptoms))
		symptoms += S
	return

// Simply removes the symptom.
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
	symptoms -= S
	return

/*

	Static Procs

*/

// Mix a list of advance diseases and return the mixed result.
/proc/Advance_Mix(var/list/D_list)

	//world << "Mixing!!!!"

	var/list/diseases = list()

	for(var/datum/disease/advance/A in D_list)
		diseases += A.Copy()

	if(!diseases.len)
		return null
	if(diseases.len <= 1)
		return pick(diseases) // Just return the only entry.

	var/i = 0
	// Mix our diseases until we are left with only one result.
	while(i < 20 && diseases.len > 1)

		i++

		var/datum/disease/advance/D1 = pick(diseases)
		diseases -= D1

		var/datum/disease/advance/D2 = pick(diseases)
		D2.Mix(D1)

	 // Should be only 1 entry left, but if not let's only return a single entry
	//world << "END MIXING!!!!!"
	var/datum/disease/advance/to_return = pick(diseases)
	to_return.Refresh(1)
	return to_return

/proc/SetViruses(datum/reagent/R, list/data)
	if(data)
		var/list/preserve = list()
		if(istype(data) && data["viruses"])
			for(var/datum/disease/A in data["viruses"])
				preserve += A.Copy()
			R.data = data.Copy()
		if(preserve.len)
			R.data["viruses"] = preserve

/proc/AdminCreateVirus(client/user)

	if(!user)
		return

	var/i = 5

	var/datum/disease/advance/D = new(0, null)
	D.symptoms = list()

	var/list/symptoms = list()
	symptoms += "Done"
	symptoms += list_symptoms.Copy()
	do
		if(user)
			var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms
			if(isnull(symptom))
				return
			else if(istext(symptom))
				i = 0
			else if(ispath(symptom))
				var/datum/symptom/S = new symptom
				if(!D.HasSymptom(S))
					D.symptoms += S
					i -= 1
	while(i > 0)

	if(D.symptoms.len > 0)

		var/new_name = stripped_input(user, "Name your new disease.", "New Name")
		if(!new_name)
			return
		D.AssignName(new_name)
		D.Refresh()

		for(var/datum/disease/advance/AD in SSdisease.processing)
			AD.Refresh()

		for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
			if(H.z != 1)
				continue
			if(!H.HasDisease(D))
				H.ForceContractDisease(D)
				break

		var/list/name_symptoms = list()
		for(var/datum/symptom/S in D.symptoms)
			name_symptoms += S.name
		message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")

/*
/mob/verb/test()

	for(var/datum/disease/D in SSdisease.processing)
		src << "[D.name] - [D.holder]"
*/

/datum/disease/advance/proc/totalStageSpeed()
	var/total_stage_speed = 0
	for(var/i in symptoms)
		var/datum/symptom/S = i
		total_stage_speed += S.stage_speed
	return total_stage_speed

/datum/disease/advance/proc/totalStealth()
	var/total_stealth = 0
	for(var/i in symptoms)
		var/datum/symptom/S = i
		total_stealth += S.stealth
	return total_stealth

/datum/disease/advance/proc/totalResistance()
	var/total_resistance = 0
	for(var/i in symptoms)
		var/datum/symptom/S = i
		total_resistance += S.resistance
	return total_resistance

/datum/disease/advance/proc/totalTransmittable()
	var/total_transmittable = 0
	for(var/i in symptoms)
		var/datum/symptom/S = i
		total_transmittable += S.transmittable
	return total_transmittable

#undef RANDOM_STARTING_LEVEL


code:
// Cold

/datum/disease/advance/cold/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Cold"
		symptoms = list(new/datum/symptom/sneeze)
	..(process, D, copy)

// Flu

/datum/disease/advance/flu/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Flu"
		symptoms = list(new/datum/symptom/cough)
	..(process, D, copy)

// Voice Changing

/datum/disease/advance/voice_change/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Epiglottis Mutation"
		symptoms = list(new/datum/symptom/voice_change)
	..(process, D, copy)

// Toxin Filter

/datum/disease/advance/heal/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Liver Enhancer"
		symptoms = list(new/datum/symptom/heal)
	..(process, D, copy)

// Hullucigen

/datum/disease/advance/hullucigen/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Reality Impairment"
		symptoms = list(new/datum/symptom/hallucigen)
	..(process, D, copy)

// Sensory Restoration

/datum/disease/advance/sensory_restoration/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Reality Enhancer"
		symptoms = list(new/datum/symptom/sensory_restoration)
	..(process, D, copy)

// Sensory Destruction

/datum/disease/advance/sensory_destruction/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Reality Destruction"
		symptoms = list(new/datum/symptom/sensory_destruction)
	..(process, D, copy)

/datum/disease/advance/inert/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
	if(!D)
		name = "Inert Virus"
		symptoms = list(new/datum/symptom/inert_virus)
	..(process, D, copy)


code:
/*
//////////////////////////////////////
Facial Hypertrichosis

	Very very Noticable.
	Decreases resistance slightly.
	Decreases stage speed.
	Reduced transmittability
	Intense Level.

BONUS
	Makes the mob grow a massive beard, regardless of gender.

//////////////////////////////////////
*/

/datum/symptom/beard

	name = "Facial Hypertrichosis"
	stealth = -3
	resistance = -1
	stage_speed = -3
	transmittable = -1
	level = 4
	severity = 1

/datum/symptom/beard/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		if(istype(M, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = M
			switch(A.stage)
				if(1, 2)
					H << "Your chin itches."
					if(H.facial_hair_style == "Shaved")
						H.facial_hair_style = "Jensen Beard"
						H.update_hair()
				if(3, 4)
					H << "You feel tough."
					if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard"))
						H.facial_hair_style = "Full Beard"
						H.update_hair()
				else
					H << "You feel manly!"
					if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard"))
						H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard")
						H.update_hair()
	return


code:
/*
//////////////////////////////////////

Choking

	Very very noticable.
	Lowers resistance.
	Decreases stage speed.
	Decreases transmittablity tremendously.
	Moderate Level.

Bonus
	Inflicts spikes of oxyloss

//////////////////////////////////////
*/

/datum/symptom/choking

	name = "Choking"
	stealth = -3
	resistance = -2
	stage_speed = -2
	transmittable = -4
	level = 3
	severity = 3

/datum/symptom/choking/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2)
				M << "[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]"
			if(3, 4)
				M << "[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]"
				Choke_stage_3_4(M, A)
				M.emote("gasp")
			else
				M << "[pick("You're choking!", "You can't breathe!")]"
				Choke(M, A)
				M.emote("gasp")
	return

/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
	var/get_damage = (sqrt(20+A.totalStageSpeed())/2)+(sqrt(16+A.totalStealth())*1)
	M.adjustOxyLoss(get_damage)
	return 1

/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
	var/get_damage = (sqrt(20+A.totalStageSpeed())/2)+(sqrt(16+A.totalStealth()*5))
	M.adjustOxyLoss(get_damage)
	return 1


code:
/*
//////////////////////////////////////

Confusion

	Little bit hidden.
	Lowers resistance.
	Decreases stage speed.
	Not very transmittable.
	Intense Level.

Bonus
	Makes the affected mob be confused for short periods of time.

//////////////////////////////////////
*/

/datum/symptom/confusion

	name = "Confusion"
	stealth = 1
	resistance = -1
	stage_speed = -3
	transmittable = 0
	level = 4
	severity = 2

/datum/symptom/confusion/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/carbon/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("Your head hurts.", "Your mind blanks for a moment.")]"
			else
				M << "You can't think straight!"
				M.confused = min(100, M.confused + 8)

	return


code:
/*
//////////////////////////////////////

Coughing

	Noticable.
	Little Resistance.
	Doesn't increase stage speed much.
	Transmittable.
	Low Level.

BONUS
	Will force the affected mob to drop small items!

//////////////////////////////////////
*/

/datum/symptom/cough

	name = "Cough"
	stealth = -1
	resistance = 3
	stage_speed = 1
	transmittable = 2
	level = 1
	severity = 1

/datum/symptom/cough/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3)
				M << "[pick("You swallow excess mucus.", "You lightly cough.")]"
			else
				M.emote("cough")
				var/obj/item/I = M.get_active_hand()
				if(I && I.w_class == 1)
					M.drop_item()
	return


code:
/*
//////////////////////////////////////

Damage Converter

	Little bit hidden.
	Lowers resistance tremendously.
	Decreases stage speed tremendously.
	Reduced transmittablity
	Intense Level.

Bonus
	Slowly converts brute/fire damage to toxin.

//////////////////////////////////////
*/

/datum/symptom/damage_converter

	name = "Toxic Compensation"
	stealth = 1
	resistance = -4
	stage_speed = -4
	transmittable = -2
	level = 4

/datum/symptom/damage_converter/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 10))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(4, 5)
				Convert(M)
	return

/datum/symptom/damage_converter/proc/Convert(mob/living/M)

	var/get_damage = rand(1, 2)

	if(istype(M, /mob/living/carbon/human))
		var/mob/living/carbon/human/H = M

		var/list/parts = H.get_damaged_organs(1,1) //1,1 because it needs inputs.

		if(!parts.len)
			return

		for(var/obj/item/organ/limb/L in parts)
			L.heal_damage(get_damage, get_damage, 0)
		M.adjustToxLoss(get_damage*parts.len)

	else
		if(M.getFireLoss() > 0 || M.getBruteLoss() > 0)
			M.adjustFireLoss(-get_damage)
			M.adjustBruteLoss(-get_damage)
			M.adjustToxLoss(get_damage)
		else
			return

	return 1


code:
/*
//////////////////////////////////////

Deafness

	Slightly noticable.
	Lowers resistance.
	Decreases stage speed slightly.
	Decreases transmittablity.
	Intense Level.

Bonus
	Causes intermittent loss of hearing.

//////////////////////////////////////
*/

/datum/symptom/deafness

	name = "Deafness"
	stealth = -1
	resistance = -2
	stage_speed = -1
	transmittable = -3
	level = 4
	severity = 3

/datum/symptom/deafness/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(3, 4)
				M << "[pick("You hear a ringing in your ear.", "Your ears pop.")]"
			if(5)
				if(!(M.ear_deaf))
					M << "Your ears pop and begin ringing loudly!"
					M.setEarDamage(-1,INFINITY) //Shall be enough
					spawn(200)
						if(M)
							M << "The ringing in your ears fades..."
							M.setEarDamage(-1,0)
	return


code:
/*
//////////////////////////////////////

Dizziness

	Hidden.
	Lowers resistance considerably.
	Decreases stage speed.
	Reduced transmittability
	Intense Level.

Bonus
	Shakes the affected mob's screen for short periods.

//////////////////////////////////////
*/

/datum/symptom/dizzy // Not the egg

	name = "Dizziness"
	stealth = 2
	resistance = -2
	stage_speed = -3
	transmittable = -1
	level = 4
	severity = 2

/datum/symptom/dizzy/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("You feel dizzy.", "Your head spins.")]"
			else
				M << "A wave of dizziness washes over you!"
				M.Dizzy(5)
	return


code:
/*
//////////////////////////////////////

Fever

	No change to hidden.
	Increases resistance.
	Increases stage speed.
	Little transmittable.
	Low level.

Bonus
	Heats up your body.

//////////////////////////////////////
*/

/datum/symptom/fever

	name = "Fever"
	stealth = 0
	resistance = 3
	stage_speed = 3
	transmittable = 2
	level = 2
	severity = 2

/datum/symptom/fever/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/carbon/M = A.affected_mob
		M << "[pick("You feel hot.", "You feel like you're burning.")]"
		if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
			Heat(M, A)

	return

/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A)
	var/get_heat = (sqrt(21+A.totalTransmittable()*2))+(sqrt(20+A.totalStageSpeed()*3))
	M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
	return 1


code:
/*
//////////////////////////////////////

Spontaneous Combustion

	Slightly hidden.
	Lowers resistance tremendously.
	Decreases stage tremendously.
	Decreases transmittablity tremendously.
	Fatal Level.

Bonus
	Ignites infected mob.

//////////////////////////////////////
*/

/datum/symptom/fire

	name = "Spontaneous Combustion"
	stealth = 1
	resistance = -4
	stage_speed = -4
	transmittable = -4
	level = 6
	severity = 5

/datum/symptom/fire/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(3)
				M << "[pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")]"
			if(4)
				Firestacks_stage_4(M, A)
				M.IgniteMob()
				M << "Your skin bursts into flames!"
				M.emote("scream")
			if(5)
				Firestacks_stage_5(M, A)
				M.IgniteMob()
				M << "Your skin erupts into an inferno!"
				M.emote("scream")
	return

/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
	var/get_stacks = (sqrt(20+A.totalStageSpeed()*2))-(sqrt(16+A.totalStealth()))
	M.adjust_fire_stacks(get_stacks)
	M.adjustFireLoss(get_stacks/2)
	return 1

/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
	var/get_stacks = (sqrt(20+A.totalStageSpeed()*3))-(sqrt(16+A.totalStealth()))
	M.adjust_fire_stacks(get_stacks)
	M.adjustFireLoss(get_stacks)
	return 1


code:
/*
//////////////////////////////////////

Necrotizing Fasciitis (AKA Flesh-Eating Disease)

	Very very noticable.
	Lowers resistance tremendously.
	No changes to stage speed.
	Decreases transmittablity temrendously.
	Fatal Level.

Bonus
	Deals brute damage over time.

//////////////////////////////////////
*/

/datum/symptom/flesh_eating

	name = "Necrotizing Fasciitis"
	stealth = -3
	resistance = -4
	stage_speed = 0
	transmittable = -4
	level = 6
	severity = 5

/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(2,3)
				M << "[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]"
			if(4,5)
				M << "[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]"
				Flesheat(M, A)
	return

/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
	var/get_damage = ((sqrt(16-A.totalStealth()))*5)
	M.adjustBruteLoss(get_damage)
	return 1


code:
/*
//////////////////////////////////////

DNA Saboteur

	Very noticable.
	Lowers resistance tremendously.
	No changes to stage speed.
	Decreases transmittablity tremendously.
	Fatal Level.

Bonus
	Cleans the DNA of a person and then randomly gives them a disability.

//////////////////////////////////////
*/

/datum/symptom/genetic_mutation

	name = "Deoxyribonucleic Acid Saboteur"
	stealth = -2
	resistance = -3
	stage_speed = 0
	transmittable = -3
	level = 6
	severity = 3
	var/list/possible_mutations
	var/archived_dna = null

/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 5)) // 15% chance
		var/mob/living/carbon/M = A.affected_mob
		if(!M.has_dna())
			return
		switch(A.stage)
			if(4, 5)
				M << "[pick("Your skin feels itchy.", "You feel light headed.")]"
				M.dna.remove_mutation_group(possible_mutations)
				randmut(M, possible_mutations)
	return

// Archive their DNA before they were infected.
/datum/symptom/genetic_mutation/Start(datum/disease/advance/A)
	possible_mutations = (bad_mutations | not_good_mutations) - mutations_list[RACEMUT]
	var/mob/living/carbon/M = A.affected_mob
	if(M)
		if(!M.has_dna())
			return
		archived_dna = M.dna.struc_enzymes

// Give them back their old DNA when cured.
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
	var/mob/living/carbon/M = A.affected_mob
	if(M && archived_dna)
		if(!M.has_dna())
			return
		M.dna.struc_enzymes = archived_dna
		M.domutcheck()


code:
/*
//////////////////////////////////////

Hallucigen

	Very noticable.
	Lowers resistance considerably.
	Decreases stage speed.
	Reduced transmittable.
	Critical Level.

Bonus
	Makes the affected mob be hallucinated for short periods of time.

//////////////////////////////////////
*/

/datum/symptom/hallucigen

	name = "Hallucigen"
	stealth = -2
	resistance = -3
	stage_speed = -3
	transmittable = -1
	level = 5
	severity = 3

/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/carbon/M = A.affected_mob
		switch(A.stage)
			if(1, 2)
				M << "[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whispher with no source.", "Your head aches.")]"
			if(3, 4)
				M << "[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]"
			else
				M << "[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]"
				M.hallucination += 5

	return


code:
/*
//////////////////////////////////////

Headache

	Noticable.
	Highly resistant.
	Increases stage speed.
	Not transmittable.
	Low Level.

BONUS
	Displays an annoying message!
	Should be used for buffing your disease.

//////////////////////////////////////
*/

/datum/symptom/headache

	name = "Headache"
	stealth = -1
	resistance = 4
	stage_speed = 2
	transmittable = 0
	level = 1
	severity = 1

/datum/symptom/headache/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		M << "[pick("Your head hurts.", "Your head starts pounding.")]"
	return


code:
/*
//////////////////////////////////////

Healing

	Little bit hidden.
	Lowers resistance tremendously.
	Decreases stage speed tremendously.
	Decreases transmittablity temrendously.
	Fatal Level.

Bonus
	Heals toxins in the affected mob's blood stream.

//////////////////////////////////////
*/

/datum/symptom/heal

	name = "Toxic Filter"
	stealth = 1
	resistance = -4
	stage_speed = -4
	transmittable = -4
	level = 6

/datum/symptom/heal/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 10))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(4, 5)
				Heal(M, A)
	return

/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
	var/get_damage = (sqrt(20+A.totalStageSpeed())*(1+rand()))
	M.adjustToxLoss(-get_damage)
	return 1

/*
//////////////////////////////////////

Metabolism

	Little bit hidden.
	Lowers resistance.
	Decreases stage speed.
	Decreases transmittablity temrendously.
	High Level.

Bonus
	Cures all diseases (except itself) and creates anti-bodies for them until the symptom dies.

//////////////////////////////////////
*/

/datum/symptom/heal/metabolism

	name = "Anti-Bodies Metabolism"
	stealth = -1
	resistance = -1
	stage_speed = -1
	transmittable = -4
	level = 3
	var/list/cured_diseases = list()

/datum/symptom/heal/metabolism/Heal(mob/living/M, datum/disease/advance/A)
	var/cured = 0
	for(var/datum/disease/D in M.viruses)
		if(D != A)
			cured = 1
			cured_diseases += D.GetDiseaseID()
			D.cure()
	if(cured)
		M << "You feel much better."

/datum/symptom/heal/metabolism/End(datum/disease/advance/A)
	// Remove all the diseases we cured.
	var/mob/living/M = A.affected_mob
	if(istype(M))
		if(cured_diseases.len)
			for(var/res in M.resistances)
				if(res in cured_diseases)
					M.resistances -= res
		M << "You feel weaker."

/*
//////////////////////////////////////

Longevity

	Medium hidden boost.
	Large resistance boost.
	Large stage speed boost.
	Large transmittablity boost.
	High Level.

Bonus
	After a certain amount of time the symptom will cure itself.

//////////////////////////////////////
*/

/datum/symptom/heal/longevity

	name = "Longevity"
	stealth = 3
	resistance = 4
	stage_speed = 4
	transmittable = 4
	level = 3
	var/longevity = 30

/datum/symptom/heal/longevity/Heal(mob/living/M, datum/disease/advance/A)
	longevity -= 1
	if(!longevity)
		A.cure()

/datum/symptom/heal/longevity/Start(datum/disease/advance/A)
	longevity = rand(initial(longevity) - 5, initial(longevity) + 5)

/*
//////////////////////////////////////

	DNA Restoration

	Not well hidden.
	Lowers resistance minorly.
	Does not affect stage speed.
	Decreases transmittablity greatly.
	Very high level.

Bonus
	Heals brain damage, treats radiation, cleans SE of non-power mutations.

//////////////////////////////////////
*/

/datum/symptom/heal/dna

	name = "Deoxyribonucleic Acid Restoration"
	stealth = -1
	resistance = -1
	stage_speed = 0
	transmittable = -3
	level = 5

/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
	var/amt_healed = (sqrt(20+A.totalStageSpeed()*(3+rand())))-(sqrt(16+A.totalStealth()*rand()))
	M.adjustBrainLoss(-amt_healed)
	//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
	var/list/unclean_mutations = (not_good_mutations|bad_mutations) - mutations_list[RACEMUT]
	M.dna.remove_mutation_group(unclean_mutations)
	M.radiation = max(M.radiation - 3, 0)
	return 1


code:
/*
//////////////////////////////////////

Inert Virus

	Base Symptom for Pandemic mutations.
	Lowers resistance tremendously.
	Decreases stage tremendously.
	Decreases transmittablity tremendously.
	Fatal Level. Can kill with boredom.

Bonus
	Disapears after Virus gets another symptom.

//////////////////////////////////////
*/

/datum/symptom/inert_virus

	name = "Inert Virus"
	stealth = 0
	resistance = 0
	stage_speed = 0
	transmittable = 0
	level = 10
	severity = 0

/datum/symptom/inert_virus/Activate(datum/disease/advance/A)
	..()
	return


code:
/*
//////////////////////////////////////

Itching

	Not noticable or unnoticable.
	Resistant.
	Increases stage speed.
	Little transmittable.
	Low Level.

BONUS
	Displays an annoying message!
	Should be used for buffing your disease.

//////////////////////////////////////
*/

/datum/symptom/itching

	name = "Itching"
	stealth = 0
	resistance = 3
	stage_speed = 3
	transmittable = 1
	level = 1
	severity = 1

/datum/symptom/itching/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		M << "Your [pick("back", "arm", "leg", "elbow", "head")] itches."
	return


code:
/*
//////////////////////////////////////

Self-Respiration

	Slightly hidden.
	Lowers resistance significantly.
	Decreases stage speed significantly.
	Decreases transmittablity tremendously.
	Fatal Level.

Bonus
	The body generates salbutamol.

//////////////////////////////////////
*/

/datum/symptom/oxygen

	name = "Self-Respiration"
	stealth = 1
	resistance = -3
	stage_speed = -3
	transmittable = -4
	level = 6

/datum/symptom/oxygen/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 5))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(4, 5)
				if (M.reagents.get_reagent_amount("salbutamol") < 20)
					M.reagents.add_reagent("salbutamol", 20)
			else
				if(prob(SYMPTOM_ACTIVATION_PROB * 5))
					M << "[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]"
	return


code:
/*
//////////////////////////////////////
Sensory-Restoration
	Very very very very noticable.
	Lowers resistance tremendously.
	Decreases stage speed tremendously.
	Decreases transmittablity tremendously.
	Fatal.
Bonus
	The body generates Sensory restorational chemicals.
	inacusiate for ears
	antihol for removal of alcohol
	synaptizine to purge sensory hallucigens
	mannitol to kickstart the mind

//////////////////////////////////////
*/
/datum/symptom/sensory_restoration
	name = "Sensory Restoration"
	stealth = -1
	resistance = -4
	stage_speed = -4
	transmittable = -3
	level = 6
	severity = 0

/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 3))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(2)
				if(M.reagents.get_reagent_amount("inacusiate")<10)
					M.reagents.add_reagent("inacusiate"=10)
					M << "Your hearing feels clearer and crisp."
			if(3)
				if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 )
					M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10))
					M << "You feel sober."
			if(4)
				if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaptizine") < 10)
					M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10, "synaptizine"=5))
					M << "You feel focused."
			if(5)
				if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaptizine") < 10 && M.reagents.get_reagent_amount("mannitol") < 10)
					M.reagents.add_reagent_list(list("mannitol"=10, "antihol"=10, "inacusiate"=10, "synaptizine"=10))
					M << "Your mind feels relaxed."
	return

/*
//////////////////////////////////////
Sensory-Destruction
	noticable.
	Lowers resistance
	Decreases stage speed tremendously.
	Decreases transmittablity tremendously.
	the drugs hit them so hard they have to focus on not dying

Bonus
	The body generates Sensory destructive chemicals.
	You cannot taste anything anymore.
	ethanol for extremely drunk victim
	mindbreaker to break the mind
	impedrezene to ruin the brain

//////////////////////////////////////
*/
/datum/symptom/sensory_destruction
	name = "Sensory destruction"
	stealth = -1
	resistance = -2
	stage_speed = -3
	transmittable = -4
	level = 6
	severity = 5

/datum/symptom/sensory_destruction/Activate(var/datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1)
				M << "You can't taste a thing."
			if(2)
				M << "You can't feel anything."
				if(prob(10))
					M.reagents.add_reagent("morphine",rand(5,7))
			if(3)
				M.reagents.add_reagent("ethanol",rand(5,7))
				M << "You feel absolutely hammered."
				if(prob(15))
					M.reagents.add_reagent("morphine",rand(5,7))
			if(4)
				M.reagents.add_reagent_list(list("ethanol",rand(7,15),"mindbreaker",rand(5,10)))
				M << "You try to focus on not dying."
				if(prob(20))
					M.reagents.add_reagent("morphine",rand(5,7))
			if(5)
				M.reagents.add_reagent_list(list("impedrezene",rand(5,15),"ethanol",rand(7,20),"mindbreaker",rand(5,15)))
				M << "u can count 2 potato!"
				if(prob(25))
					M.reagents.add_reagent("morphine",rand(5,7))
	return


code:
/*
//////////////////////////////////////
Alopecia

	Noticable.
	Decreases resistance slightly.
	Reduces stage speed slightly.
	Transmittable.
	Intense Level.

BONUS
	Makes the mob lose hair.

//////////////////////////////////////
*/

/datum/symptom/shedding

	name = "Alopecia"
	stealth = -1
	resistance = -1
	stage_speed = -1
	transmittable = 2
	level = 4
	severity = 1

/datum/symptom/shedding/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		M << "[pick("Your scalp itches.", "Your skin feels flakey.")]"
		if(istype(M, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = M
			switch(A.stage)
				if(3, 4)
					if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair"))
						H << "Your hair starts to fall out in clumps..."
						spawn(50)
							H.hair_style = "Balding Hair"
							H.update_hair()
				if(5)
					if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald"))
						H << "Your hair starts to fall out in clumps..."
						spawn(50)
							H.facial_hair_style = "Shaved"
							H.hair_style = "Bald"
							H.update_hair()
	return


code:
/*
//////////////////////////////////////

Shivering

	No change to hidden.
	Increases resistance.
	Increases stage speed.
	Little transmittable.
	Low level.

Bonus
	Cools down your body.

//////////////////////////////////////
*/

/datum/symptom/shivering

	name = "Shivering"
	stealth = 0
	resistance = 2
	stage_speed = 2
	transmittable = 2
	level = 2
	severity = 2

/datum/symptom/shivering/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/carbon/M = A.affected_mob
		M << "[pick("You feel cold.", "You start shivering.")]"
		if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
			Chill(M, A)
	return

/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
	var/get_cold = (sqrt(16+A.totalStealth()*2))+(sqrt(21+A.totalResistance()*2))
	M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
	return 1


code:
/*
//////////////////////////////////////
Vitiligo

	Extremely Noticable.
	Decreases resistance slightly.
	Reduces stage speed slightly.
	Reduces transmission.
	Critical Level.

BONUS
	Makes the mob lose skin pigmentation.

//////////////////////////////////////
*/

/datum/symptom/vitiligo

	name = "Vitiligo"
	stealth = -3
	resistance = -1
	stage_speed = -1
	transmittable = -2
	level = 4
	severity = 1

/datum/symptom/vitiligo/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		if(istype(M, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = M
			if(H.skin_tone == "albino")
				return
			switch(A.stage)
				if(5)
					H.skin_tone = "albino"
					H.update_body(0)
				else
					H.visible_message("[H] looks a bit pale...", "Your skin suddenly appears lighter...")

	return

/*
//////////////////////////////////////
Revitiligo

	Extremely Noticable.
	Decreases resistance slightly.
	Reduces stage speed slightly.
	Reduces transmission.
	Critical Level.

BONUS
	Makes the mob gain skin pigmentation.

//////////////////////////////////////
*/

/datum/symptom/revitiligo

	name = "Revitiligo"
	stealth = -3
	resistance = -1
	stage_speed = -1
	transmittable = -2
	level = 4
	severity = 1

/datum/symptom/revitiligo/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		if(istype(M, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = M
			if(H.skin_tone == "african2")
				return
			switch(A.stage)
				if(5)
					H.skin_tone = "african2"
					H.update_body(0)
				else
					H.visible_message("[H] looks a bit dark...", "Your skin suddenly appears darker...")

	return


code:
/*
//////////////////////////////////////

Sneezing

	Very Noticable.
	Increases resistance.
	Doesn't increase stage speed.
	Very transmittable.
	Low Level.

Bonus
	Forces a spread type of AIRBORNE
	with extra range!

//////////////////////////////////////
*/

/datum/symptom/sneeze

	name = "Sneezing"
	stealth = -2
	resistance = 3
	stage_speed = 0
	transmittable = 4
	level = 1
	severity = 1

/datum/symptom/sneeze/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3)
				M.emote("sniff")
			else
				M.emote("sneeze")
				A.spread(A.holder, 5)
	return


code:
/*
//////////////////////////////////////

Stimulant //gotta go fast

	Noticable.
	Lowers resistance significantly.
	Decreases stage speed moderately..
	Decreases transmittablity tremendously.
	Moderate Level.

Bonus
	The body generates Ephedrine.

//////////////////////////////////////
*/

/datum/symptom/stimulant

	name = "Stimulant"
	stealth = -1
	resistance = -3
	stage_speed = -2
	transmittable = -4
	level = 3

/datum/symptom/stimulant/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 10))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(5)
				if (M.reagents.get_reagent_amount("ephedrine") < 10)
					M.reagents.add_reagent("ephedrine", 10)
			else
				if(prob(SYMPTOM_ACTIVATION_PROB * 5))
					M << "[pick("You feel restless.", "You feel like running laps around the station.")]"
	return


code:
// Symptoms are the effects that engineered advanced diseases do.

var/list/list_symptoms = subtypesof(/datum/symptom)
var/list/dictionary_symptoms = list()

var/global/const/SYMPTOM_ACTIVATION_PROB = 3

/datum/symptom
	// Buffs/Debuffs the symptom has to the overall engineered disease.
	var/name = ""
	var/stealth = 0
	var/resistance = 0
	var/stage_speed = 0
	var/transmittable = 0
	// The type level of the symptom. Higher is harder to generate.
	var/level = 0
	// The severity level of the symptom. Higher is more dangerous.
	var/severity = 0
	// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
	var/id = ""

/datum/symptom/New()
	var/list/S = list_symptoms
	for(var/i = 1; i <= S.len; i++)
		if(src.type == S[i])
			id = "[i]"
			return
	CRASH("We couldn't assign an ID!")

// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
	return

// Called when the advance disease is going to be deleted or when the advance disease stops processing.
/datum/symptom/proc/End(datum/disease/advance/A)
	return

/datum/symptom/proc/Activate(datum/disease/advance/A)
	return


code:
/*
//////////////////////////////////////
Viral adaptation

	Moderate stealth boost.
	Major Increases to resistance.
	Reduces stage speed.
	No change to transmission
	Critical Level.

BONUS
	Extremely useful for buffing viruses

//////////////////////////////////////
*/
/datum/symptom/viraladaptation
	name = "Viral self-adaptation"
	stealth = 3
	resistance = 5
	stage_speed = -3
	transmittable = 0
	level = 3

/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1)
				M << "You feel off, but no different from before."
			if(5)
				M << "You feel better, but nothing interesting happens."

/*
//////////////////////////////////////
Viral evolution

	Moderate stealth reductopn.
	Major decreases to resistance.
	increases stage speed.
	increase to transmission
	Critical Level.

BONUS
	Extremely useful for buffing viruses

//////////////////////////////////////
*/
/datum/symptom/viralevolution
	name = "Viral evolutionary acceleration"
	stealth = -2
	resistance = -3
	stage_speed = 5
	transmittable = 3
	level = 3

/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1)
				M << "You feel better, but no different from before."
			if(5)
				M << "You feel off, but nothing interesting happens."


code:
/*
//////////////////////////////////////

Hyphema (Eye bleeding)

	Slightly noticable.
	Lowers resistance tremendously.
	Decreases stage speed tremendously.
	Decreases transmittablity.
	Critical Level.

Bonus
	Causes blindness.

//////////////////////////////////////
*/

/datum/symptom/visionloss

	name = "Hyphema"
	stealth = -1
	resistance = -4
	stage_speed = -4
	transmittable = -3
	level = 5
	severity = 4

/datum/symptom/visionloss/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2)
				M << "Your eyes itch."
			if(3, 4)
				M << "Your eyes burn!"
				M.blur_eyes(10)
				M.adjust_eye_damage(1)
			else
				M << "Your eyes burn horrificly!"
				M.blur_eyes(20)
				M.adjust_eye_damage(5)
				if(M.eye_damage >= 10)
					M.become_nearsighted()
					if(prob(M.eye_damage - 10 + 1))
						if(M.become_blind())
							M << "You go blind!"

/*
//////////////////////////////////////

Ocular Restoration

	Noticable.
	Lowers resistance significantly.
	Decreases stage speed moderately..
	Decreases transmittablity tremendously.
	High level.

Bonus
	Restores eyesight.

//////////////////////////////////////
*/

/datum/symptom/visionaid

	name = "Ocular Restoration"
	stealth = -1
	resistance = -3
	stage_speed = -2
	transmittable = -4
	level = 4

/datum/symptom/visionaid/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 5))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(4, 5)
				if (M.reagents.get_reagent_amount("oculine") < 20)
					M.reagents.add_reagent("oculine", 20)
			else
				if(prob(SYMPTOM_ACTIVATION_PROB * 5))
					M << "[pick("Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")]"
	return


code:
/*
//////////////////////////////////////

Voice Change

	Very Very noticable.
	Lowers resistance considerably.
	Decreases stage speed.
	Reduced transmittable.
	Fatal Level.

Bonus
	Changes the voice of the affected mob. Causing confusion in communication.

//////////////////////////////////////
*/

/datum/symptom/voice_change

	name = "Voice Change"
	stealth = -2
	resistance = -3
	stage_speed = -3
	transmittable = -1
	level = 6
	severity = 2

/datum/symptom/voice_change/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))

		var/mob/living/carbon/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("Your throat hurts.", "You clear your throat.")]"
			else
				if(ishuman(M))
					var/mob/living/carbon/human/H = M
					H.SetSpecialVoice(H.dna.species.random_name(H.gender))

	return

/datum/symptom/voice_change/End(datum/disease/advance/A)
	..()
	if(ishuman(A.affected_mob))
		var/mob/living/carbon/human/H = A.affected_mob
		H.UnsetSpecialVoice()
	return


code:
/*
//////////////////////////////////////

Vomiting

	Very Very Noticable.
	Decreases resistance.
	Doesn't increase stage speed.
	Little transmittable.
	Medium Level.

Bonus
	Forces the affected mob to vomit!
	Meaning your disease can spread via
	people walking on vomit.
	Makes the affected mob lose nutrition and
	heal toxin damage.

//////////////////////////////////////
*/

/datum/symptom/vomit

	name = "Vomiting"
	stealth = -2
	resistance = -1
	stage_speed = 0
	transmittable = 1
	level = 3
	severity = 4

/datum/symptom/vomit/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB / 2))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("You feel nauseous.", "You feel like you're going to throw up!")]"
			else
				Vomit(M)

	return

/datum/symptom/vomit/proc/Vomit(mob/living/carbon/M)
	M.vomit(20)

/*
//////////////////////////////////////

Vomiting Blood

	Very Very Noticable.
	Decreases resistance.
	Decreases stage speed.
	Little transmittable.
	Intense level.

Bonus
	Forces the affected mob to vomit blood!
	Meaning your disease can spread via
	people walking on the blood.
	Makes the affected mob lose health.

//////////////////////////////////////
*/

/datum/symptom/vomit/blood

	name = "Blood Vomiting"
	stealth = -2
	resistance = -1
	stage_speed = -1
	transmittable = 1
	level = 4
	severity = 5

/datum/symptom/vomit/blood/Vomit(mob/living/carbon/M)
	M.vomit(0, 1)

/*
//////////////////////////////////////

Projectile Vomiting

	Very Very Noticable.
	Decreases resistance.
	Doesn't increase stage speed.
	Little transmittable.
	Medium Level.

Bonus
	As normal vomiting, except it will spread further,
	likely causing more to walk across the vomit.

//////////////////////////////////////
*/

/datum/symptom/vomit/projectile

	name = "Projectile Vomiting"
	stealth = -2
	level = 4

/datum/symptom/vomit/projectile/Vomit(mob/living/carbon/M)
	M.vomit(6,0,1,5,1)


code:
/*
//////////////////////////////////////

Weakness

	Slightly noticeable.
	Lowers resistance slightly.
	Decreases stage speed moderately.
	Decreases transmittablity moderately.
	Moderate Level.

Bonus
	Deals stamina damage to the host

//////////////////////////////////////
*/

/datum/symptom/weakness

	name = "Weakness"
	stealth = -1
	resistance = -1
	stage_speed = -2
	transmittable = -2
	level = 3
	severity = 3

/datum/symptom/weakness/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2)
				M << "[pick("You feel weak.", "You feel lazy.")]"
			if(3, 4)
				M << "[pick("You feel very frail.", "You think you might faint.")]"
				M.adjustStaminaLoss(15)
			else
				M << "[pick("You feel tremendously weak!", "Your body trembles as exhaustion creeps over you.")]"
				M.adjustStaminaLoss(30)
				if(M.getStaminaLoss() > 60 && !M.stat)
					M.visible_message("[M] faints!", "You swoon and faint...")
					M.AdjustSleeping(5)
	return


code:
/*
//////////////////////////////////////

Weight Gain

	Very Very Noticable.
	Decreases resistance.
	Decreases stage speed.
	Reduced transmittable.
	Intense Level.

Bonus
	Increases the weight gain of the mob,
	forcing it to eventually turn fat.
//////////////////////////////////////
*/

/datum/symptom/weight_gain

	name = "Weight Gain"
	stealth = -3
	resistance = -3
	stage_speed = -2
	transmittable = -2
	level = 4
	severity = 1

/datum/symptom/weight_gain/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("You feel blubbery.", "Your stomach hurts.")]"
			else
				M.overeatduration = min(M.overeatduration + 100, 600)
				M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL)

	return

/*
//////////////////////////////////////

Weight Loss

	Very Very Noticable.
	Decreases resistance.
	Decreases stage speed.
	Reduced Transmittable.
	High level.

Bonus
	Decreases the weight of the mob,
	forcing it to be skinny.

//////////////////////////////////////
*/

/datum/symptom/weight_loss

	name = "Weight Loss"
	stealth = -3
	resistance = -2
	stage_speed = -2
	transmittable = -2
	level = 3
	severity = 1

/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(1, 2, 3, 4)
				M << "[pick("You feel hungry.", "You crave for food.")]"
			else
				M << "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]"
				M.overeatduration = max(M.overeatduration - 100, 0)
				M.nutrition = max(M.nutrition - 100, 0)

	return

/*
//////////////////////////////////////

Weight Even

	Very Noticable.
	Decreases resistance.
	Decreases stage speed.
	Reduced transmittable.
	High level.

Bonus
	Causes the weight of the mob to
	be even, meaning eating isn't
	required anymore.

//////////////////////////////////////
*/

/datum/symptom/weight_even

	name = "Weight Even"
	stealth = -3
	resistance = -2
	stage_speed = -2
	transmittable = -2
	level = 4

/datum/symptom/weight_even/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB))
		var/mob/living/M = A.affected_mob
		switch(A.stage)
			if(4, 5)
				M.overeatduration = 0
				M.nutrition = NUTRITION_LEVEL_WELL_FED + 50

	return


code:
/*
//////////////////////////////////////
Eternal Youth

	Moderate stealth boost.
	Increases resistance tremendously.
	Increases stage speed tremendously.
	Reduces transmission tremendously.
	Critical Level.

BONUS
	Gives you immortality and eternal youth!!!
	Can be used to buff your virus

//////////////////////////////////////
*/

/datum/symptom/youth

	name = "Eternal Youth"
	stealth = 3
	resistance = 4
	stage_speed = 4
	transmittable = -4
	level = 5

/datum/symptom/youth/Activate(datum/disease/advance/A)
	..()
	if(prob(SYMPTOM_ACTIVATION_PROB * 2))
		var/mob/living/M = A.affected_mob
		if(istype(M, /mob/living/carbon/human))
			var/mob/living/carbon/human/H = M
			switch(A.stage)
				if(1)
					if(H.age > 41)
						H.age = 41
						H << "You haven't had this much energy in years!"
				if(2)
					if(H.age > 36)
						H.age = 36
						H << "You're suddenly in a good mood."
				if(3)
					if(H.age > 31)
						H.age = 31
						H << "You begin to feel more lithe."
				if(4)
					if(H.age > 26)
						H.age = 26
						H << "You feel reinvigorated."
				if(5)
					if(H.age > 21)
						H.age = 21
						H << "You feel like you can take on the world!"

	return


code:
/datum/disease/anxiety
	name = "Severe Anxiety"
	form = "Infection"
	max_stages = 4
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Ethanol"
	cures = list("ethanol")
	agent = "Excess Lepidopticides"
	viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
	desc = "If left untreated subject will regurgitate butterflies."
	severity = MEDIUM

/datum/disease/anxiety/stage_act()
	..()
	switch(stage)
		if(2) //also changes say, see say.dm
			if(prob(5))
				affected_mob << "You feel anxious."
		if(3)
			if(prob(10))
				affected_mob << "Your stomach flutters."
			if(prob(5))
				affected_mob << "You feel panicky."
			if(prob(2))
				affected_mob << "You're overtaken with panic!"
				affected_mob.confused += (rand(2,3))
		if(4)
			if(prob(10))
				affected_mob << "You feel butterflies in your stomach."
			if(prob(5))
				affected_mob.visible_message("[affected_mob] stumbles around in a panic.", \
												"You have a panic attack!")
				affected_mob.confused += (rand(6,8))
				affected_mob.jitteriness += (rand(6,8))
			if(prob(2))
				affected_mob.visible_message("[affected_mob] coughs up butterflies!", \
													"You cough up butterflies!")
				new /mob/living/simple_animal/butterfly(affected_mob.loc)
				new /mob/living/simple_animal/butterfly(affected_mob.loc)
	return


code:
/datum/disease/appendicitis
	form = "Condition"
	name = "Appendicitis"
	max_stages = 3
	cure_text = "Surgery"
	agent = "Shitty Appendix"
	viable_mobtypes = list(/mob/living/carbon/human)
	permeability_mod = 1
	desc = "If left untreated the subject will become very weak, and may vomit often."
	severity = "Dangerous!"
	longevity = 1000
	disease_flags = CAN_CARRY|CAN_RESIST
	spread_flags = NON_CONTAGIOUS
	visibility_flags = HIDDEN_PANDEMIC
	required_organs = list(/obj/item/organ/internal/appendix)

/datum/disease/appendicitis/stage_act()
	..()
	switch(stage)
		if(1)
			if(prob(5))
				affected_mob.emote("cough")
		if(2)
			var/obj/item/organ/internal/appendix/A = affected_mob.getorgan(/obj/item/organ/internal/appendix)
			if(A)
				A.inflamed = 1
				A.update_icon()
			if(prob(3))
				affected_mob << "You feel a stabbing pain in your abdomen!"
				affected_mob.Stun(rand(2,3))
				affected_mob.adjustToxLoss(1)
		if(3)
			if(prob(1))
				affected_mob.vomit(95)


code:
/datum/disease/beesease
	name = "Beesease"
	form = "Infection"
	max_stages = 4
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Sugar"
	cures = list("sugar")
	agent = "Apidae Infection"
	viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
	desc = "If left untreated subject will regurgitate bees."
	severity = DANGEROUS

/datum/disease/beesease/stage_act()
	..()
	switch(stage)
		if(2) //also changes say, see say.dm
			if(prob(2))
				affected_mob << "You taste honey in your mouth."
		if(3)
			if(prob(10))
				affected_mob << "Your stomach rumbles."
			if(prob(2))
				affected_mob << "Your stomach stings painfully."
				if(prob(20))
					affected_mob.adjustToxLoss(2)
					affected_mob.updatehealth()
		if(4)
			if(prob(10))
				affected_mob.visible_message("[affected_mob] buzzes.", \
												"Your stomach buzzes violently!")
			if(prob(5))
				affected_mob << "You feel something moving in your throat."
			if(prob(1))
				affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \
													"You cough up a swarm of bees!")
				new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc)
		//if(5)
		//Plus if you die, you explode into bees
	return


code:
/datum/disease/brainrot
	name = "Brainrot"
	max_stages = 4
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Mannitol"
	cures = list("mannitol")
	agent = "Cryptococcus Cosmosis"
	viable_mobtypes = list(/mob/living/carbon/human)
	cure_chance = 15//higher chance to cure, since two reagents are required
	desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
	required_organs = list(/obj/item/organ/limb/head)
	severity = DANGEROUS

/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR
	..()

	switch(stage)
		if(2)
			if(prob(2))
				affected_mob.emote("blink")
			if(prob(2))
				affected_mob.emote("yawn")
			if(prob(2))
				affected_mob << "You don't feel like yourself."
			if(prob(5))
				affected_mob.adjustBrainLoss(1)
				affected_mob.updatehealth()
		if(3)
			if(prob(2))
				affected_mob.emote("stare")
			if(prob(2))
				affected_mob.emote("drool")
			if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now
				affected_mob.adjustBrainLoss(2)
				affected_mob.updatehealth()
				if(prob(2))
					affected_mob << "Your try to remember something important...but can't."

		if(4)
			if(prob(2))
				affected_mob.emote("stare")
			if(prob(2))
				affected_mob.emote("drool")
			if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now
				affected_mob.adjustBrainLoss(3)
				affected_mob.updatehealth()
				if(prob(2))
					affected_mob << "Strange buzzing fills your head, removing all thoughts."
			if(prob(3))
				affected_mob << "You lose consciousness..."
				affected_mob.visible_message("[affected_mob] suddenly collapses")
				affected_mob.Paralyse(rand(5,10))
				if(prob(1))
					affected_mob.emote("snore")
			if(prob(15))
				affected_mob.stuttering += 3

	return


code:
/datum/disease/cold
	name = "The Cold"
	max_stages = 3
	spread_flags = AIRBORNE
	cure_text = "Rest & Spaceacillin"
	cures = list("spaceacillin")
	agent = "XY-rhinovirus"
	viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
	permeability_mod = 0.5
	desc = "If left untreated the subject will contract the flu."
	severity = MINOR

/datum/disease/cold/stage_act()
	..()
	switch(stage)
		if(2)
/*
			if(affected_mob.sleeping && prob(40))  //removed until sleeping is fixed
				affected_mob << "\blue You feel better."
				cure()
				return
*/
			if(affected_mob.lying && prob(40))  //changed FROM prob(10) until sleeping is fixed
				affected_mob << "You feel better."
				cure()
				return
			if(prob(1) && prob(5))
				affected_mob << "You feel better."
				cure()
				return
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your throat feels sore."
			if(prob(1))
				affected_mob << "Mucous runs down the back of your throat."
		if(3)
/*
			if(affected_mob.sleeping && prob(25))  //removed until sleeping is fixed
				affected_mob << "\blue You feel better."
				cure()
				return
*/
			if(affected_mob.lying && prob(25))  //changed FROM prob(5) until sleeping is fixed
				affected_mob << "You feel better."
				cure()
				return
			if(prob(1) && prob(1))
				affected_mob << "You feel better."
				cure()
				return
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your throat feels sore."
			if(prob(1))
				affected_mob << "Mucous runs down the back of your throat."
			if(prob(1) && prob(50))
				if(!affected_mob.resistances.Find(/datum/disease/flu))
					var/datum/disease/Flu = new /datum/disease/flu(0)
					affected_mob.ContractDisease(Flu)
					cure()


code:
/datum/disease/cold9
	name = "The Cold"
	max_stages = 3
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Common Cold Anti-bodies & Spaceacillin"
	cures = list("spaceacillin")
	agent = "ICE9-rhinovirus"
	viable_mobtypes = list(/mob/living/carbon/human)
	desc = "If left untreated the subject will slow, as if partly frozen."
	severity = MEDIUM

/datum/disease/cold9/stage_act()
	..()
	switch(stage)
		if(2)
			affected_mob.bodytemperature -= 10
			if(prob(1) && prob(10))
				affected_mob << "You feel better."
				cure()
				return
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your throat feels sore."
			if(prob(5))
				affected_mob << "You feel stiff."
		if(3)
			affected_mob.bodytemperature -= 20
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your throat feels sore."
			if(prob(10))
				affected_mob << "You feel stiff."


code:
/datum/disease/dnaspread
	name = "Space Retrovirus"
	max_stages = 4
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Mutadone"
	cures = list("mutadone")
	disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
	agent = "S4E1 retrovirus"
	viable_mobtypes = list(/mob/living/carbon/human)
	var/datum/dna/original_dna = null
	var/transformed = 0
	desc = "This disease transplants the genetic code of the initial vector into new hosts."
	severity = MEDIUM

/datum/disease/dnaspread/stage_act()
	..()
	if(!affected_mob.dna)
		cure()
	if(affected_mob.dna.species.specflags & NOTRANSSTING) //Only species that can be spread by transformation sting can be spread by the retrovirus
		cure()

	if(!strain_data["dna"])
		//Absorbs the target DNA.
		strain_data["dna"] = new affected_mob.dna.type
		affected_mob.dna.copy_dna(strain_data["dna"])
		src.carrier = 1
		src.stage = 4
		return

	switch(stage)
		if(2 || 3) //Pretend to be a cold and give time to spread.
			if(prob(8))
				affected_mob.emote("sneeze")
			if(prob(8))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your muscles ache."
				if(prob(20))
					affected_mob.take_organ_damage(1)
			if(prob(1))
				affected_mob << "Your stomach hurts."
				if(prob(20))
					affected_mob.adjustToxLoss(2)
					affected_mob.updatehealth()
		if(4)
			if(!transformed && !carrier)
				//Save original dna for when the disease is cured.
				original_dna = new affected_mob.dna.type
				affected_mob.dna.copy_dna(original_dna)

				affected_mob << "You don't feel like yourself.."
				var/datum/dna/transform_dna = strain_data["dna"]

				transform_dna.transfer_identity(affected_mob, transfer_SE = 1)
				affected_mob.real_name = affected_mob.dna.real_name
				affected_mob.updateappearance(mutcolor_update=1)
				affected_mob.domutcheck()

				transformed = 1
				carrier = 1 //Just chill out at stage 4

	return

/datum/disease/dnaspread/Destroy()
	if (original_dna && transformed && affected_mob)
		original_dna.transfer_identity(affected_mob, transfer_SE = 1)
		affected_mob.real_name = affected_mob.dna.real_name
		affected_mob.updateappearance(mutcolor_update=1)
		affected_mob.domutcheck()

		affected_mob << "You feel more like yourself."
	return ..()


code:
/datum/disease/fake_gbs
	name = "GBS"
	max_stages = 5
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Synaptizine & Sulfur"
	cures = list("synaptizine","sulfur")
	agent = "Gravitokinetic Bipotential SADS-"
	viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
	desc = "If left untreated death will occur."
	severity = BIOHAZARD

/datum/disease/fake_gbs/stage_act()
	..()
	switch(stage)
		if(2)
			if(prob(1))
				affected_mob.emote("sneeze")
		if(3)
			if(prob(5))
				affected_mob.emote("cough")
			else if(prob(5))
				affected_mob.emote("gasp")
			if(prob(10))
				affected_mob << "You're starting to feel very weak..."
		if(4)
			if(prob(10))
				affected_mob.emote("cough")

		if(5)
			if(prob(10))
				affected_mob.emote("cough")


code:
/datum/disease/flu
	name = "The Flu"
	max_stages = 3
	spread_text = "Airborne"
	cure_text = "Spaceacillin"
	cures = list("spaceacillin")
	cure_chance = 10
	agent = "H13N1 flu virion"
	viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
	permeability_mod = 0.75
	desc = "If left untreated the subject will feel quite unwell."
	severity = MEDIUM

/datum/disease/flu/stage_act()
	..()
	switch(stage)
		if(2)
			if(affected_mob.lying && prob(20))
				affected_mob << "You feel better."
				stage--
				return
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your muscles ache."
				if(prob(20))
					affected_mob.take_organ_damage(1)
			if(prob(1))
				affected_mob << "Your stomach hurts."
				if(prob(20))
					affected_mob.adjustToxLoss(1)
					affected_mob.updatehealth()

		if(3)
			if(affected_mob.lying && prob(15))
				affected_mob << "You feel better."
				stage--
				return
			if(prob(1))
				affected_mob.emote("sneeze")
			if(prob(1))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "Your muscles ache."
				if(prob(20))
					affected_mob.take_organ_damage(1)
			if(prob(1))
				affected_mob << "Your stomach hurts."
				if(prob(20))
					affected_mob.adjustToxLoss(1)
					affected_mob.updatehealth()
	return


code:
/datum/disease/fluspanish
	name = "Spanish inquisition Flu"
	max_stages = 3
	spread_text = "Airborne"
	cure_text = "Spaceacillin & Anti-bodies to the common flu"
	cures = list("spaceacillin")
	cure_chance = 10
	agent = "1nqu1s1t10n flu virion"
	viable_mobtypes = list(/mob/living/carbon/human)
	permeability_mod = 0.75
	desc = "If left untreated the subject will burn to death for being a heretic."
	severity = DANGEROUS

/datum/disease/fluspanish/stage_act()
	..()
	switch(stage)
		if(2)
			affected_mob.bodytemperature += 10
			if(prob(5))
				affected_mob.emote("sneeze")
			if(prob(5))
				affected_mob.emote("cough")
			if(prob(1))
				affected_mob << "You're burning in your own skin!"
				affected_mob.take_organ_damage(0,5)

		if(3)
			affected_mob.bodytemperature += 20
			if(prob(5))
				affected_mob.emote("sneeze")
			if(prob(5))
				affected_mob.emote("cough")
			if(prob(5))
				affected_mob << "You're burning in your own skin!"
				affected_mob.take_organ_damage(0,5)
	return


code:
/datum/disease/gbs
	name = "GBS"
	max_stages = 5
	spread_text = "On contact"
	spread_flags = CONTACT_GENERAL
	cure_text = "Synaptizine & Sulfur"
	cures = list("synaptizine","sulfur")
	cure_chance = 15//higher chance to cure, since two reagents are required
	agent = "Gravitokinetic Bipotential SADS+"
	viable_mobtypes = list(/mob/living/carbon/human)
	disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
	permeability_mod = 1
	severity = BIOHAZARD

/datum/disease/gbs/stage_act()
	..()
	switch(stage)
		if(2)
			if(prob(45))
				affected_mob.adjustToxLoss(5)
				affected_mob.updatehealth()
			if(prob(1))
				affected_mob.emote("sneeze")
		if(3)
			if(prob(5))
				affected_mob.emote("cough")
			else if(prob(5))
				affected_mob.emote("gasp")
			if(prob(10))
				affected_mob << "You're starting to feel very weak..."
		if(4)
			if(prob(10))
				affected_mob.emote("cough")
			affected_mob.adjustToxLoss(5)
			affected_mob.updatehealth()
		if(5)
			affected_mob << "Your body feels as if it's trying to rip itself open..."
			if(prob(50))
				affected_mob.gib()
		else
			return