code:
#define LING_FAKEDEATH_TIME					400 //40 seconds
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP	50	//The lowest value of geneticdamage handle_changeling() can take it to while dead.
#define LING_ABSORB_RECENT_SPEECH			8	//The amount of recent spoken lines to gain on absorbing a mob

var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
var/list/slot2slot = list("head" = slot_head, "wear_mask" = slot_wear_mask, "back" = slot_back, "wear_suit" = slot_wear_suit, "w_uniform" = slot_w_uniform, "shoes" = slot_shoes, "belt" = slot_belt, "gloves" = slot_gloves, "glasses" = slot_glasses, "ears" = slot_ears, "wear_id" = slot_wear_id, "s_store" = slot_s_store)
var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling)

/datum/game_mode
	var/list/datum/mind/changelings = list()

/datum/game_mode/changeling
	name = "changeling"
	config_tag = "changeling"
	antag_flag = ROLE_CHANGELING
	restricted_jobs = list("AI", "Cyborg")
	protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
	required_players = 15
	required_enemies = 1
	recommended_enemies = 4
	reroll_friendly = 1

	var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
	var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
	var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target

	var/const/prob_int_item = 50 // intercept names the theft target half the time
	var/const/prob_right_item_l = 25 // lower bound on probability of naming right theft target
	var/const/prob_right_item_h = 50 // upper bound on probability of naming the right theft target

	var/const/prob_int_sab_target = 50 // intercept names the sabotage target half the time
	var/const/prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target
	var/const/prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target

	var/const/prob_right_killer_l = 25 //lower bound on probability of naming the right operative
	var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative
	var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly
	var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly

	var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off

	var/changeling_team_objective_type = null //If this is not null, we hand our this objective to all lings

/datum/game_mode/changeling/announce()
	world << "The current game mode is - Changeling!"
	world << "There are alien changelings on the station. Do not let the changelings succeed!"

/datum/game_mode/changeling/pre_setup()

	if(config.protect_roles_from_antagonist)
		restricted_jobs += protected_jobs

	if(config.protect_assistant_from_antagonist)
		restricted_jobs += "Assistant"

	var/num_changelings = 1

	if(config.changeling_scaling_coeff)
		num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) ))
	else
		num_changelings = max(1, min(num_players(), changeling_amount))

	if(antag_candidates.len>0)
		for(var/i = 0, i < num_changelings, i++)
			if(!antag_candidates.len) break
			var/datum/mind/changeling = pick(antag_candidates)
			antag_candidates -= changeling
			changelings += changeling
			changeling.restricted_roles = restricted_jobs
			modePlayer += changelings
		return 1
	else
		return 0

/datum/game_mode/changeling/post_setup()

	//Decide if it's ok for the lings to have a team objective
	//And then set it up to be handed out in forge_changeling_objectives
	var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
	var/list/possible_team_objectives = list()
	for(var/T in team_objectives)
		var/datum/objective/changeling_team_objective/CTO = T

		if(changelings.len >= initial(CTO.min_lings))
			possible_team_objectives += T

	if(possible_team_objectives.len && prob(20*changelings.len))
		changeling_team_objective_type = pick(possible_team_objectives)

	for(var/datum/mind/changeling in changelings)
		log_game("[changeling.key] (ckey) has been selected as a changeling")
		changeling.current.make_changeling()
		changeling.special_role = "Changeling"
		forge_changeling_objectives(changeling)
		greet_changeling(changeling)
		ticker.mode.update_changeling_icons_added(changeling)
	..()
	return

/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
	var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(joined_player_list.len/config.changeling_scaling_coeff) )
	if(ticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
		return
	if(ticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
		if(ROLE_CHANGELING in character.client.prefs.be_special)
			if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
				if(age_check(character.client))
					if(!(character.job in restricted_jobs))
						character.mind.make_Changling()

/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling, var/team_mode = 0)
	//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
	//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
	//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone

	var/escape_objective_possible = TRUE

	//if there's a team objective, check if it's compatible with escape objectives
	for(var/datum/objective/changeling_team_objective/CTO in changeling.objectives)
		if(!CTO.escape_objective_compatible)
			escape_objective_possible = FALSE
			break

	var/datum/objective/absorb/absorb_objective = new
	absorb_objective.owner = changeling
	absorb_objective.gen_amount_goal(6, 8)
	changeling.objectives += absorb_objective

	if(prob(60))
		var/datum/objective/steal/steal_objective = new
		steal_objective.owner = changeling
		steal_objective.find_target()
		changeling.objectives += steal_objective

	var/list/active_ais = active_ais()
	if(active_ais.len && prob(100/joined_player_list.len))
		var/datum/objective/destroy/destroy_objective = new
		destroy_objective.owner = changeling
		destroy_objective.find_target()
		changeling.objectives += destroy_objective
	else
		if(prob(70))
			var/datum/objective/assassinate/kill_objective = new
			kill_objective.owner = changeling
			if(team_mode) //No backstabbing while in a team
				kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
			else
				kill_objective.find_target()
			changeling.objectives += kill_objective
		else
			var/datum/objective/maroon/maroon_objective = new
			maroon_objective.owner = changeling
			if(team_mode)
				maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
			else
				maroon_objective.find_target()
			changeling.objectives += maroon_objective

			if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
				var/datum/objective/escape/escape_with_identity/identity_theft = new
				identity_theft.owner = changeling
				identity_theft.target = maroon_objective.target
				identity_theft.update_explanation_text()
				changeling.objectives += identity_theft
				escape_objective_possible = FALSE

	if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
		if(prob(50))
			var/datum/objective/escape/escape_objective = new
			escape_objective.owner = changeling
			changeling.objectives += escape_objective
		else
			var/datum/objective/escape/escape_with_identity/identity_theft = new
			identity_theft.owner = changeling
			if(team_mode)
				identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
			else
				identity_theft.find_target()
			changeling.objectives += identity_theft
		escape_objective_possible = FALSE

/datum/game_mode/changeling/forge_changeling_objectives(datum/mind/changeling)
	if(changeling_team_objective_type)
		var/datum/objective/changeling_team_objective/team_objective = new changeling_team_objective_type
		team_objective.owner = changeling
		changeling.objectives += team_objective

		..(changeling,1)
	else
		..(changeling,0)

/datum/game_mode/proc/greet_changeling(datum/mind/changeling, you_are=1)
	if (you_are)
		changeling.current << "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human."
	changeling.current << "Use say \":g message\" to communicate with your fellow changelings."
	changeling.current << "You must complete the following tasks:"

	if (changeling.current.mind)
		var/mob/living/carbon/human/H = changeling.current
		if(H.mind.assigned_role == "Clown")
			H << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
			H.dna.remove_mutation(CLOWNMUT)

	var/obj_count = 1
	for(var/datum/objective/objective in changeling.objectives)
		changeling.current << "Objective #[obj_count]: [objective.explanation_text]"
		obj_count++
	return

/*/datum/game_mode/changeling/check_finished()
	var/changelings_alive = 0
	for(var/datum/mind/changeling in changelings)
		if(!istype(changeling.current,/mob/living/carbon))
			continue
		if(changeling.current.stat==2)
			continue
		changelings_alive++

	if (changelings_alive)
		changelingdeath = 0
		return ..()
	else
		if (!changelingdeath)
			changelingdeathtime = world.time
			changelingdeath = 1
		if(world.time-changelingdeathtime > TIME_TO_GET_REVIVED)
			return 1
		else
			return ..()
	return 0*/

/datum/game_mode/proc/auto_declare_completion_changeling()
	if(changelings.len)
		var/text = "
The changelings were:"
		for(var/datum/mind/changeling in changelings)
			var/changelingwin = 1
			if(!changeling.current)
				changelingwin = 0

			text += printplayer(changeling)

			//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
			text += "
Changeling ID: [changeling.changeling.changelingID]."
			text += "
Genomes Extracted: [changeling.changeling.absorbedcount]"

			if(changeling.objectives.len)
				var/count = 1
				for(var/datum/objective/objective in changeling.objectives)
					if(objective.check_completion())
						text += "
Objective #[count]: [objective.explanation_text] Success!"
						feedback_add_details("changeling_objective","[objective.type]|SUCCESS")
					else
						text += "
Objective #[count]: [objective.explanation_text] Fail."
						feedback_add_details("changeling_objective","[objective.type]|FAIL")
						changelingwin = 0
					count++

			if(changelingwin)
				text += "
The changeling was successful!"
				feedback_add_details("changeling_success","SUCCESS")
			else
				text += "
The changeling has failed."
				feedback_add_details("changeling_success","FAIL")
			text += "
"

		world << text

	return 1

/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
	var/list/stored_profiles = list() //list of datum/changelingprofile
	var/datum/changelingprofile/first_prof = null
	//var/list/absorbed_dna = list()
	//var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
	var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
	var/absorbedcount = 0
	var/chem_charges = 20
	var/chem_storage = 75
	var/chem_recharge_rate = 1
	var/chem_recharge_slowdown = 0
	var/sting_range = 2
	var/changelingID = "Changeling"
	var/geneticdamage = 0
	var/isabsorbing = 0
	var/geneticpoints = 10
	var/purchasedpowers = list()
	var/mimicing = ""
	var/canrespec = 0
	var/changeling_speak = 0
	var/datum/dna/chosen_dna
	var/obj/effect/proc_holder/changeling/sting/chosen_sting

/datum/changeling/New(var/gender=FEMALE)
	..()
	var/honorific
	if(gender == FEMALE)
		honorific = "Ms."
	else
		honorific = "Mr."
	if(possible_changeling_IDs.len)
		changelingID = pick(possible_changeling_IDs)
		possible_changeling_IDs -= changelingID
		changelingID = "[honorific] [changelingID]"
	else
		changelingID = "[honorific] [rand(1,999)]"

/datum/changeling/proc/regenerate(var/mob/living/carbon/the_ling)
	if(istype(the_ling))
		if(the_ling.stat == DEAD)
			chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
			geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
		else //not dead? no chem/geneticdamage caps.
			chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
			geneticdamage = max(0, geneticdamage-1)

/datum/changeling/proc/get_dna(dna_owner)
	for(var/datum/changelingprofile/prof in stored_profiles)
		if(dna_owner == prof.name)
			return prof

/datum/changeling/proc/has_dna(datum/dna/tDNA)
	for(var/datum/changelingprofile/prof in stored_profiles)
		if(tDNA.is_same_as(prof.dna))
			return 1
	return 0

/datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/human/target, var/verbose=1)
	if(stored_profiles.len)
		var/datum/changelingprofile/prof = stored_profiles[1]
		if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
			if(verbose)
				user << "We have reached our capacity to store genetic information! We must transform before absorbing more."
			return
	if(!target)
		return
	if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
		if(verbose)
			user << "DNA of [target] is ruined beyond usability!"
		return
	if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
		if(verbose)
			user << "We could gain no benefit from absorbing a lesser creature."
		return
	if(has_dna(target.dna))
		if(verbose)
			user << "We already have this DNA in storage!"
		return
	if(!target.has_dna())
		if(verbose)
			user << "[target] is not compatible with our biology."
		return
	return 1

/datum/changeling/proc/create_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
	var/datum/changelingprofile/prof = new

	H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
	var/datum/dna/new_dna = new H.dna.type
	H.dna.copy_dna(new_dna)
	prof.dna = new_dna
	prof.name = H.real_name
	prof.protected = protect

	prof.underwear = H.underwear
	prof.undershirt = H.undershirt
	prof.socks = H.socks

	var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
	for(var/slot in slots)
		if(slot in H.vars)
			var/obj/item/I = H.vars[slot]
			if(!I)
				continue
			prof.name_list[slot] = I.name
			prof.appearance_list[slot] = I.appearance
			prof.flags_cover_list[slot] = I.flags_cover
			prof.item_color_list[slot] = I.item_color
			prof.item_state_list[slot] = I.item_state
			prof.exists_list[slot] = 1
		else
			continue

	return prof

/datum/changeling/proc/add_profile(datum/changelingprofile/prof)
	if(stored_profiles.len > dna_max)
		if(!push_out_profile())
			return

	stored_profiles += prof
	absorbedcount++

/datum/changeling/proc/add_new_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
	var/datum/changelingprofile/prof = create_profile(H, protect)
	add_profile(prof)
	return prof

/datum/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
	for(var/datum/changelingprofile/prof in stored_profiles)
		if(H.real_name == prof.name)
			if(prof.protected && !force)
				continue
			stored_profiles -= prof
			qdel(prof)

/datum/changeling/proc/get_profile_to_remove()
	for(var/datum/changelingprofile/prof in stored_profiles)
		if(!prof.protected)
			return prof

/datum/changeling/proc/push_out_profile()
	var/datum/changelingprofile/removeprofile = get_profile_to_remove()
	if(removeprofile)
		stored_profiles -= removeprofile
		return 1
	return 0

/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
	var/datum/dna/chosen_dna = chosen_prof.dna
	user.real_name = chosen_prof.name
	user.underwear = chosen_prof.underwear
	user.undershirt = chosen_prof.undershirt
	user.socks = chosen_prof.socks

	chosen_dna.transfer_identity(user, 1)
	user.updateappearance(mutcolor_update=1)
	user.update_body()
	user.domutcheck()

	//vars hackery. not pretty, but better than the alternative.
	for(var/slot in slots)
		if(istype(user.vars[slot], slot2type[slot]) && !(chosen_prof.exists_list[slot])) //remove unnecessary flesh items
			qdel(user.vars[slot])
			continue

		if((user.vars[slot] && !istype(user.vars[slot], slot2type[slot])) || !(chosen_prof.exists_list[slot]))
			continue

		var/obj/item/C
		var/equip = 0
		if(!user.vars[slot])
			var/thetype = slot2type[slot]
			equip = 1
			C = new thetype(user)

		else if(istype(user.vars[slot], slot2type[slot]))
			C = user.vars[slot]

		C.appearance = chosen_prof.appearance_list[slot]
		C.name = chosen_prof.name_list[slot]
		C.flags_cover = chosen_prof.flags_cover_list[slot]
		C.item_color = chosen_prof.item_color_list[slot]
		C.item_state = chosen_prof.item_state_list[slot]
		if(equip)
			user.equip_to_slot_or_del(C, slot2slot[slot])

	user.regenerate_icons()

/datum/changelingprofile
	var/name = "a bug"

	var/protected = 0

	var/datum/dna/dna = null
	var/list/name_list = list() //associative list of slotname = itemname
	var/list/appearance_list = list()
	var/list/flags_cover_list = list()
	var/list/exists_list = list()
	var/list/item_color_list = list()
	var/list/item_state_list = list()

	var/underwear
	var/undershirt
	var/socks

/datum/changelingprofile/Destroy()
	qdel(dna)
	return ..()

/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
	newprofile.name = name
	newprofile.protected = protected
	newprofile.dna = new dna.type
	dna.copy_dna(newprofile.dna)
	newprofile.name_list = name_list.Copy()
	newprofile.appearance_list = appearance_list.Copy()
	newprofile.flags_cover_list = flags_cover_list.Copy()
	newprofile.exists_list = exists_list.Copy()
	newprofile.item_color_list = item_color_list.Copy()
	newprofile.item_state_list = item_state_list.Copy()
	newprofile.underwear = underwear
	newprofile.undershirt = undershirt
	newprofile.socks = socks

/datum/game_mode/proc/update_changeling_icons_added(datum/mind/changling_mind)
	var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_CHANGELING]
	hud.join_hud(changling_mind.current)
	set_antag_hud(changling_mind.current, "changling")

/datum/game_mode/proc/update_changeling_icons_removed(datum/mind/changling_mind)
	var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_CHANGELING]
	hud.leave_hud(changling_mind.current)
	set_antag_hud(changling_mind.current, null)


code:
/*
 * Don't use the apostrophe in name or desc. Causes script errors.
 * TODO: combine atleast some of the functionality with /proc_holder/spell
 */

/obj/effect/proc_holder/changeling
	panel = "Changeling"
	name = "Prototype Sting"
	desc = "" // Fluff
	var/helptext = "" // Details
	var/chemical_cost = 0 // negative chemical cost is for passive abilities (chemical glands)
	var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase, -1 = cannot be purchased
	var/req_dna = 0  //amount of dna needed to use this ability. Changelings always have atleast 1
	var/req_human = 0 //if you need to be human to use this ability
	var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD
	var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss.
	var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet.

/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user)
	return

/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
	return

/obj/effect/proc_holder/changeling/Click()
	var/mob/user = usr
	if(!user || !user.mind || !user.mind.changeling)
		return
	try_to_sting(user)

/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target)
	if(!can_sting(user, target))
		return
	var/datum/changeling/c = user.mind.changeling
	if(sting_action(user, target))
		sting_feedback(user, target)
		take_chemical_cost(c)

/obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target)
	return 0

/obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target)
	return 0

/obj/effect/proc_holder/changeling/proc/take_chemical_cost(datum/changeling/changeling)
	changeling.chem_charges -= chemical_cost
	changeling.geneticdamage += genetic_damage

//Fairly important to remember to return 1 on success >.<
/obj/effect/proc_holder/changeling/proc/can_sting(mob/user, mob/target)
	if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards
		return 0
	if(req_human && !ishuman(user))
		user << "We cannot do that in this form!"
		return 0
	var/datum/changeling/c = user.mind.changeling
	if(c.chem_charges<chemical_cost)
		user << "We require at least [chemical_cost] unit\s of chemicals to do that!"
		return 0
	if(c.absorbedcount<req_dna)
		user << "We require at least [req_dna] sample\s of compatible DNA."
		return 0
	if(req_stat < user.stat)
		user << "We are incapacitated."
		return 0
	if((user.status_flags & FAKEDEATH) && name != "Regenerate")
		user << "We are incapacitated."
		return 0
	if(c.geneticdamage > max_genetic_damage)
		user << "Our genomes are still reassembling. We need time to recover first."
		return 0
	return 1

//used in /mob/Stat()
/obj/effect/proc_holder/changeling/proc/can_be_used_by(mob/user)
	if(!ishuman(user) && !ismonkey(user))
		return 0
	if(req_human && !ishuman(user))
		return 0
	return 1

license: mit


code:
var/list/sting_paths
// totally stolen from the new player panel.  YAYY

/obj/effect/proc_holder/changeling/evolution_menu
	name = "-Evolution Menu-" //Dashes are so it's listed before all the other abilities.
	desc = "Choose our method of subjugation."
	dna_cost = 0

/obj/effect/proc_holder/changeling/evolution_menu/Click()
	if(!usr || !usr.mind || !usr.mind.changeling)
		return
	var/datum/changeling/changeling = usr.mind.changeling

	if(!sting_paths)
		sting_paths = init_paths(/obj/effect/proc_holder/changeling)

	var/dat = create_menu(changeling)
	usr << browse(dat, "window=powers;size=600x700")//900x480

/obj/effect/proc_holder/changeling/evolution_menu/proc/create_menu(datum/changeling/changeling)
	var/dat
	dat +="<title>Changling Evolution Menu</title>"

	//javascript, the part that does most of the work~
	dat += {"

	"}

	//body tag start + onload and onkeypress (onkeyup) javascript event calls
	dat += ""

	//title + search bar
	dat += {"

					Changeling Evolution Menu

					Hover over a power to see more information

					Current ability choices remaining: [changeling.geneticpoints]

					By rendering a lifeform to a husk, we gain enough power to alter and adapt our evolutions.

					(Readapt)

					Search: <input type='text' id='filter' value='' style='width:300px;'>

	"}

	//player table header
	dat += {"

"}

	var/i = 1
	for(var/path in sting_paths)

		var/obj/effect/proc_holder/changeling/P = new path()
		if(P.dna_cost <= 0) //Let's skip the crap we start with. Keeps the evolution menu uncluttered.
			continue

		var/ownsthis = changeling.has_sting(P)

		var/color
		if(ownsthis)
			if(i%2 == 0)
				color = "#d8ebd8"
			else
				color = "#c3dec3"
		else
			if(i%2 == 0)
				color = "#f2f2f2"
			else
				color = "#e6e6e6"

		dat += {"

					Evolve [P][ownsthis ? " - Purchased" : (P.req_dna>changeling.absorbedcount ? " - Requires [P.req_dna] absorptions" : " - Cost: [P.dna_cost]")]

		"}

		i++

	//player table ending
	dat += {"

	"}
	return dat

/obj/effect/proc_holder/changeling/evolution_menu/Topic(href, href_list)
	..()
	if(!(iscarbon(usr) && usr.mind && usr.mind.changeling))
		return

	if(href_list["P"])
		usr.mind.changeling.purchasePower(usr, href_list["P"])
	else if(href_list["readapt"])
		usr.mind.changeling.lingRespec(usr)
	var/dat = create_menu(usr.mind.changeling)
	usr << browse(dat, "window=powers;size=600x700")
/////

/datum/changeling/proc/purchasePower(mob/living/carbon/user, sting_name)

	var/obj/effect/proc_holder/changeling/thepower = null

	if(!sting_paths)
		sting_paths = init_paths(/obj/effect/proc_holder/changeling)
	for(var/path in sting_paths)
		var/obj/effect/proc_holder/changeling/S = new path()
		if(S.name == sting_name)
			thepower = S

	if(thepower == null)
		user << "This is awkward. Changeling power purchase failed, please report this bug to a coder!"
		return

	if(absorbedcount < thepower.req_dna)
		user << "We lack the energy to evolve this ability!"
		return

	if(has_sting(thepower))
		user << "We have already evolved this ability!"
		return

	if(thepower.dna_cost < 0)
		user << "We cannot evolve this ability."
		return

	if(geneticpoints < thepower.dna_cost)
		user << "We have reached our capacity for abilities."
		return

	if(user.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
		user << "We lack the energy to evolve new abilities right now."
		return

	geneticpoints -= thepower.dna_cost
	purchasedpowers += thepower
	thepower.on_purchase(user)

//Reselect powers
/datum/changeling/proc/lingRespec(mob/user)
	if(!ishuman(user))
		user << "We can't remove our evolutions in this form!"
		return
	if(canrespec)
		user << "We have removed our evolutions from this form, and are now ready to readapt."
		user.remove_changeling_powers(1)
		canrespec = 0
		user.make_changeling()
		return 1
	else
		user << "You lack the power to readapt your evolutions!"
		return 0

/mob/proc/make_changeling()
	if(!mind)
		return
	if(!ishuman(src) && !ismonkey(src))
		return
	if(!mind.changeling)
		mind.changeling = new /datum/changeling(gender)
	if(!sting_paths)
		sting_paths = init_paths(/obj/effect/proc_holder/changeling)
	if(mind.changeling.purchasedpowers)
		remove_changeling_powers(1)
	// purchase free powers.
	for(var/path in sting_paths)
		var/obj/effect/proc_holder/changeling/S = new path()
		if(!S.dna_cost)
			if(!mind.changeling.has_sting(S))
				mind.changeling.purchasedpowers+=S
			S.on_purchase(src)

	var/mob/living/carbon/C = src	//only carbons have dna now, so we have to typecaste
	if(ishuman(C))
		var/datum/changelingprofile/prof = mind.changeling.add_new_profile(C, src)
		mind.changeling.first_prof = prof
	return 1

/datum/changeling/proc/reset()
	chosen_sting = null
	geneticpoints = initial(geneticpoints)
	sting_range = initial(sting_range)
	chem_storage = initial(chem_storage)
	chem_recharge_rate = initial(chem_recharge_rate)
	chem_charges = min(chem_charges, chem_storage)
	chem_recharge_slowdown = initial(chem_recharge_slowdown)
	mimicing = ""

/mob/proc/remove_changeling_powers(keep_free_powers=0)
	if(ishuman(src) || ismonkey(src))
		if(mind && mind.changeling)
			mind.changeling.changeling_speak = 0
			mind.changeling.reset()
			for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers)
				if(p.dna_cost == 0 && keep_free_powers)
					continue
				mind.changeling.purchasedpowers -= p
				p.on_refund(src)
		if(hud_used)
			hud_used.lingstingdisplay.icon_state = null
			hud_used.lingstingdisplay.invisibility = 101

/datum/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
	for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
		if(power.name == P.name)
			return 1
	return 0


code:
/obj/effect/proc_holder/changeling/absorbDNA
	name = "Absorb DNA"
	desc = "Absorb the DNA of our victim."
	chemical_cost = 0
	dna_cost = 0
	req_human = 1
	max_genetic_damage = 100

/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user)
	if(!..())
		return

	var/datum/changeling/changeling = user.mind.changeling
	if(changeling.isabsorbing)
		user << "We are already absorbing!"
		return

	var/obj/item/weapon/grab/G = user.get_active_hand()
	if(!istype(G))
		user << "We must be grabbing a creature in our active hand to absorb them!"
		return
	if(G.state <= GRAB_NECK)
		user << "We must have a tighter grip to absorb this creature!"
		return

	var/mob/living/carbon/target = G.affecting
	return changeling.can_absorb_dna(user,target)

/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user)
	var/datum/changeling/changeling = user.mind.changeling
	var/obj/item/weapon/grab/G = user.get_active_hand()
	var/mob/living/carbon/human/target = G.affecting
	changeling.isabsorbing = 1
	for(var/stage = 1, stage<=3, stage++)
		switch(stage)
			if(1)
				user << "This creature is compatible. We must hold still..."
			if(2)
				user.visible_message("[user] extends a proboscis!", "We extend a proboscis.")
			if(3)
				user.visible_message("[user] stabs [target] with the proboscis!", "We stab [target] with the proboscis.")
				target << "You feel a sharp stabbing pain!"
				target.take_overall_damage(40)

		feedback_add_details("changeling_powers","A[stage]")
		if(!do_mob(user, target, 150))
			user << "Our absorption of [target] has been interrupted!"
			changeling.isabsorbing = 0
			return

	user.visible_message("[user] sucks the fluids from [target]!", "We have absorbed [target].")
	target << "You are absorbed by the changeling!"

	if(!changeling.has_dna(target.dna))
		changeling.add_new_profile(target, user)

	if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
		user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)

	if(target.mind)//if the victim has got a mind

		target.mind.show_memory(src, 0) //I can read your mind, kekeke. Output all their notes.

		//Some of target's recent speech, so the changeling can attempt to imitate them better.
		//Recent as opposed to all because rounds tend to have a LOT of text.
		var/list/recent_speech = list()

		if(target.say_log.len > LING_ABSORB_RECENT_SPEECH)
			recent_speech = target.say_log.Copy(target.say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list
		else
			for(var/spoken_memory in target.say_log)
				if(recent_speech.len >= LING_ABSORB_RECENT_SPEECH)
					break
				recent_speech += spoken_memory

		if(recent_speech.len)
			user.mind.store_memory("Some of [target]'s speech patterns, we should study these to better impersonate them!")
			user << "Some of [target]'s speech patterns, we should study these to better impersonate them!"
			for(var/spoken_memory in recent_speech)
				user.mind.store_memory("\"[spoken_memory]\"")
				user << "\"[spoken_memory]\""
			user.mind.store_memory("We have no more knowledge of [target]'s speech patterns.")
			user << "We have no more knowledge of [target]'s speech patterns."

		if(target.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points!
			changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage)
			changeling.absorbedcount += (target.mind.changeling.absorbedcount)

			target.mind.changeling.stored_profiles.len = 1
			target.mind.changeling.absorbedcount = 0

	changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage)

	changeling.isabsorbing = 0
	changeling.canrespec = 1

	target.death(0)
	target.Drain()
	return 1

//Absorbs the target DNA.
//datum/changeling/proc/absorb_dna(mob/living/carbon/T, mob/user)

//datum/changeling/proc/store_dna(datum/dna/new_dna, mob/user)

/obj/effect/proc_holder/changeling/swap_form
	name = "Swap Forms"
	desc = "We force ourselves into the body of another form, pushing their consciousness into the form we left behind."
	helptext = "We will bring all our abilities with us, but we will lose our old form DNA in exchange for the new one. The process will seem suspicious to any observers."
	chemical_cost = 40
	dna_cost = 1
	req_human = 1 //Monkeys can't grab

/obj/effect/proc_holder/changeling/swap_form/can_sting(mob/living/carbon/user)
	if(!..())
		return
	var/obj/item/weapon/grab/G = user.get_active_hand()
	if(!istype(G) || (G.state < GRAB_AGGRESSIVE))
		user << "We must have an aggressive grab on creature in our active hand to do this!"
		return
	var/mob/living/carbon/target = G.affecting
	if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
		user << "DNA of [target] is ruined beyond usability!"
		return
	if(!ishuman(target))
		user << "[target] is not compatible with this ability."
		return
	return 1

/obj/effect/proc_holder/changeling/swap_form/sting_action(mob/living/carbon/user)
	var/obj/item/weapon/grab/G = user.get_active_hand()
	var/mob/living/carbon/target = G.affecting
	var/datum/changeling/changeling = user.mind.changeling

	user << "We tighen our grip. We must hold still...."
	target.do_jitter_animation(500)
	user.do_jitter_animation(500)

	if(!do_mob(user,target,20))
		user << "The body swap has been interrupted!"
		return

	target << "[user] tightens their grip as a painful sensation invades your body."

	if(!changeling.has_dna(target.dna))
		changeling.add_new_profile(target, user)
	changeling.remove_profile(user)

	var/mob/dead/observer/ghost = target.ghostize(0)
	user.mind.transfer_to(target)
	if(ghost)
		ghost.mind.transfer_to(user)
		if(ghost.key)
			user.key = ghost.key

	user.Paralyse(2)
	target << "Our genes cry out as we swap our [user] form for [target]."


code:
/obj/effect/proc_holder/changeling/adrenaline
	name = "Adrenaline Sacs"
	desc = "We evolve additional sacs of adrenaline throughout our body."
	helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body."
	chemical_cost = 30
	dna_cost = 2
	req_human = 1
	req_stat = UNCONSCIOUS

//Recover from stuns.
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
	user << "Energy rushes through us.[user.lying ? " We arise." : ""]"
	user.SetSleeping(0)
	user.SetParalysis(0)
	user.SetStunned(0)
	user.SetWeakened(0)
	user.reagents.add_reagent("changelingAdrenaline", 10)
	user.reagents.add_reagent("changelingAdrenaline2", 2) //For a really quick burst of speed
	user.adjustStaminaLoss(-75)
	feedback_add_details("changeling_powers","UNS")
	return 1


code:
//Augmented Eyesight: Gives you thermal and night vision - bye bye, flashlights. Also, high DNA cost because of how powerful it is.
//Possible todo: make a custom message for directing a penlight/flashlight at the eyes - not sure what would display though.

/obj/effect/proc_holder/changeling/augmented_eyesight
	name = "Augmented Eyesight"
	desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability, or protects your vision from flashes."
	helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active."
	chemical_cost = 0
	dna_cost = 2 //Would be 1 without thermal vision
	var/active = 0 //Whether or not vision is enhanced

/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user)
	if(!istype(user))
		return
	if(user.getorgan(/obj/item/organ/internal/cyberimp/eyes/thermals/ling))
		user << "Our eyes are protected from flashes."
		var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/shield/ling()
		O.Insert(user)

	else
		var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/thermals/ling()
		O.Insert(user)

	return 1

/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user)
	var/obj/item/organ/internal/cyberimp/eyes/O = user.getorganslot("eye_ling")
	if(O)
		O.Remove(user)
		qdel(O)

/obj/item/organ/internal/cyberimp/eyes/shield/ling
	name = "protective membranes"
	desc = "These variable transparency organic membranes will protect you from welders and flashes and heal your eye damage."
	icon_state = "ling_eyeshield"
	eye_color = null
	implant_overlay = null
	origin_tech = "biotech=4"
	slot = "eye_ling"
	status = ORGAN_ORGANIC

/obj/item/organ/internal/cyberimp/eyes/shield/ling/on_life()
	..()
	if(owner.eye_blind>1 || (owner.eye_blind && owner.stat !=UNCONSCIOUS) || owner.eye_damage || owner.eye_blurry || (owner.disabilities & NEARSIGHT))
		owner.reagents.add_reagent("oculine", 1)

/obj/item/organ/internal/cyberimp/eyes/shield/ling/prepare_eat()
	var/obj/S = ..()
	S.reagents.add_reagent("oculine", 15)
	return S

/obj/item/organ/internal/cyberimp/eyes/thermals/ling
	name = "heat receptors"
	desc = "These heat receptors dramatically increases eyes light sensing ability."
	icon_state = "ling_thermal"
	eye_color = null
	implant_overlay = null
	origin_tech = "biotech=5;magnets=5"
	slot = "eye_ling"
	status = ORGAN_ORGANIC
	aug_message = "You feel a minute twitch in our eyes, and darkness creeps away."

/obj/item/organ/internal/cyberimp/eyes/thermals/ling/emp_act(severity)
	return

/obj/item/organ/internal/cyberimp/eyes/thermals/ling/Insert(mob/living/carbon/M, special = 0)
	..()
	if(ishuman(owner))
		var/mob/living/carbon/human/H = owner
		H.weakeyes = 1

/obj/item/organ/internal/cyberimp/eyes/thermals/ling/Remove(mob/living/carbon/M, special = 0)
	if(ishuman(owner))
		var/mob/living/carbon/human/H = owner
		H.weakeyes = 0
	..()


code:
/obj/effect/proc_holder/changeling/biodegrade
	name = "Biodegrade"
	desc = "Dissolves restraints or other objects preventing free movement."
	helptext = "This is obvious to nearby people, and can destroy standard restraints and closets."
	chemical_cost = 30 //High cost to prevent spam
	dna_cost = 2
	req_human = 1
	genetic_damage = 10
	max_genetic_damage = 0

/obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user)
	var/used = 0
	if(!user.restrained() && !istype(user.loc, /obj/structure/closet))
		user << "We are already free!"
		return 0

	if(user.handcuffed)
		used = 1
		var/obj/O = user.get_item_by_slot(slot_handcuffed)
		if(!O || !istype(O))
			return 0
		user.visible_message("[user] vomits a glob of acid on \his [O]!", \
							 "We vomit acidic ooze onto our restraints!")
		spawn(30)
			if(O && user.handcuffed == O)
				user.unEquip(O)
				O.visible_message("[O] dissolves into a puddle of sizzling goop.")
				O.loc = get_turf(user)
				qdel(O)

	if(user.wear_suit && user.wear_suit.breakouttime && !used)
		used = 1
		var/obj/item/clothing/suit/S = user.get_item_by_slot(slot_wear_suit)
		if(!S || !istype(S))
			return 0
		user.visible_message("[user] vomits a glob of acid across the front of \his [S]!", \
							 "We vomit acidic ooze onto our straight jacket!")
		spawn(30)
			if(S && user.wear_suit == S)
				user.unEquip(S)
				S.visible_message("[S] dissolves into a puddle of sizzling goop.")
				S.loc = get_turf(user)
				qdel(S)

	if(istype(user.loc, /obj/structure/closet) && !used)
		used = 1
		var/obj/structure/closet/C = user.loc
		if(!C || !istype(C)) //The !C check slightly scares me, but...
			return 0
		C.visible_message("[C]'s hinges suddenly begin to melt and run!")
		user << "We vomit acidic goop onto the interior of [C]!"
		spawn(70)
			if(C && user.loc == C)
				C.visible_message("[C]'s door breaks and opens!")
				C.welded = 0
				C.locked = 0
				C.broken = 1
				C.open()
				user << "We open the container restraining us!"

	feedback_add_details("changeling_powers","BD")
	return 1


code:
/obj/effect/proc_holder/changeling/chameleon_skin
	name = "Chameleon Skin"
	desc = "Our skin pigmentation rapidly changes to suit our current environment."
	helptext = "Allows us to become invisible after a few seconds of standing still. Can be toggled on and off."
	dna_cost = 2
	chemical_cost = 25
	req_human = 1
	genetic_damage = 10
	max_genetic_damage = 50

/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user)
	var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
	if(!istype(H)) // req_human could be done in can_sting stuff.
		return
	var/datum/mutation/human/HM = mutations_list[CHAMELEON]
	if(HM in H.dna.mutations)
		HM.force_lose(H)
	else
		HM.force_give(H)

	feedback_add_details("changeling_powers","CS")
	return 1

/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user)
	if(user.has_dna())
		var/mob/living/carbon/C = user
		var/datum/mutation/human/HM = mutations_list[CHAMELEON]
		if(HM in C.dna.mutations)
			HM.force_lose(C)


code:
/obj/effect/proc_holder/changeling/digitalcamo
	name = "Digital Camouflage"
	desc = "By evolving the ability to distort our form and proprotions, we defeat common altgorithms used to detect lifeforms on cameras."
	helptext = "We cannot be tracked by camera or seen by AI units while using this skill. However, humans looking at us will find us... uncanny."
	dna_cost = 1

//Prevents AIs tracking you but makes you easily detectable to the human-eye.
/obj/effect/proc_holder/changeling/digitalcamo/sting_action(mob/user)

	if(user.digitalcamo)
		user << "We return to normal."
		user.digitalinvis = 0
		user.digitalcamo = 0
	else
		user << "We distort our form to hide from the AI"
		user.digitalcamo = 1
		user.digitalinvis = 1

	feedback_add_details("changeling_powers","CAM")
	return 1

/obj/effect/proc_holder/changeling/digitalcamo/on_refund(mob/user)
	user.digitalcamo = 0
	user.digitalinvis = 0


code:
/obj/effect/proc_holder/changeling/fakedeath
	name = "Regenerative Stasis"
	desc = "We fall into a stasis, allowing us to regenerate and trick our enemies."
	chemical_cost = 15
	dna_cost = 0
	req_dna = 1
	req_stat = DEAD
	max_genetic_damage = 100

//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
	user << "We begin our stasis, preparing energy to arise once more."
	user.status_flags |= FAKEDEATH		//play dead
	user.update_stat()
	user.update_canmove()
	if(user.stat != DEAD)
		user.emote("deathgasp")
		user.tod = worldtime2text()
	spawn(LING_FAKEDEATH_TIME)
		if(user && user.mind && user.mind.changeling && user.mind.changeling.purchasedpowers)
			user << "We are ready to regenerate."
			user.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
	feedback_add_details("changeling_powers","FD")
	return 1

/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
	if(user.status_flags & FAKEDEATH)
		user << "We are already regenerating."
		return
	if(!user.stat) //Confirmation for living changelings if they want to fake their death
		switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No"))
			if("No")
				return
	return ..()


code:
/obj/effect/proc_holder/changeling/fleshmend
	name = "Fleshmend"
	desc = "Our flesh rapidly regenerates, healing our wounds. Effectiveness decreases with quick, repeated use."
	helptext = "Heals a moderate amount of damage over a short period of time. Can be used while unconscious, and will alert nearby crew."
	chemical_cost = 25
	dna_cost = 2
	req_stat = UNCONSCIOUS
	var/recent_uses = 1 //The factor of which the healing should be divided by

/obj/effect/proc_holder/changeling/fleshmend/New()
	..()
	SSobj.processing.Add(src)

/obj/effect/proc_holder/changeling/fleshmend/Destroy()
	SSobj.processing.Remove(src)
	..()

/obj/effect/proc_holder/changeling/fleshmend/process()
	if(recent_uses > 1)
		recent_uses--

//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
/obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user)
	user << "We begin to heal rapidly."
	if(recent_uses > 1)
		user << "Our healing's effectiveness is reduced by quickly repeated use!"
	spawn(0)
		recent_uses++
		if(ishuman(user))
			var/mob/living/carbon/human/H = user
			H.restore_blood()
			H.remove_all_embedded_objects()

		for(var/i = 0, i < 10, i++) //The healing itself - doesn't heal toxin damage (that's anatomic panacea) and effectiveness decreases with each use in a short timespan
			if(user)
				user.adjustBruteLoss(-10 / recent_uses, 0)
				user.adjustOxyLoss(-10 / recent_uses, 0)
				user.adjustFireLoss(-10 / recent_uses, 0)
				user.updatehealth()
			sleep(10)

	feedback_add_details("changeling_powers","RR")
	return 1


code:
/obj/effect/proc_holder/changeling/headcrab
	name = "Last Resort"
	desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel."
	helptext = "We will be placed in control of a small, fragile creature. We may attack a corpse like this to plant an egg which will slowly mature into a new form for us."
	chemical_cost = 20
	dna_cost = 1
	req_human = 1

/obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user)
	var/datum/mind/M = user.mind
	var/list/organs = user.getorganszone("head", 1)

	for(var/obj/item/organ/internal/I in organs)
		I.Remove(user, 1)

	explosion(get_turf(user),0,0,2,0,silent=1)
	for(var/mob/living/carbon/human/H in range(2,user))
		H << "You are blinded by a shower of blood!"
		H.Stun(1)
		H.blur_eyes(20)
		H.adjust_eye_damage(5)
		H.confused += 3
	for(var/mob/living/silicon/S in range(2,user))
		S << "Your sensors are disabled by a shower of blood!"
		S.Weaken(3)
	var/turf = get_turf(user)
	spawn(5) // So it's not killed in explosion
		var/mob/living/simple_animal/hostile/headcrab/crab = new(turf)
		for(var/obj/item/organ/internal/I in organs)
			I.loc = crab
		crab.origin = M
		if(crab.origin)
			crab.origin.active = 1
			crab.origin.transfer_to(crab)
			crab << "You burst out of the remains of your former body in a shower of gore!"
	user.gib()
	feedback_add_details("changeling_powers","LR")
	return 1


code:
//HIVEMIND COMMUNICATION (:g)
/obj/effect/proc_holder/changeling/hivemind_comms
	name = "Hivemind Communication"
	desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
	helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
	dna_cost = 0
	chemical_cost = -1

/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(var/mob/user)
	..()
	var/datum/changeling/changeling=user.mind.changeling
	changeling.changeling_speak = 1
	user << "Use say \":g message\" to communicate with the other changelings."
	var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
	if(!changeling.has_sting(S1))
		changeling.purchasedpowers+=S1
	var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
	if(!changeling.has_sting(S2))
		changeling.purchasedpowers+=S2
	return

// HIVE MIND UPLOAD/DOWNLOAD DNA
var/list/datum/dna/hivemind_bank = list()

/obj/effect/proc_holder/changeling/hivemind_upload
	name = "Hive Channel DNA"
	desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
	chemical_cost = 10
	dna_cost = -1

/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
	var/datum/changeling/changeling = user.mind.changeling
	var/list/names = list()
	for(var/datum/changelingprofile/prof in changeling.stored_profiles)
		if(!(prof in hivemind_bank))
			names += prof.name

	if(names.len <= 0)
		user << "The airwaves already have all of our DNA."
		return

	var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
	if(!chosen_name)
		return

	var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
	if(!chosen_dna)
		return

	var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
	chosen_dna.copy_profile(uploaded_dna)
	hivemind_bank += uploaded_dna
	user << "We channel the DNA of [chosen_name] to the air."
	feedback_add_details("changeling_powers","HU")
	return 1

/obj/effect/proc_holder/changeling/hivemind_download
	name = "Hive Absorb DNA"
	desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
	chemical_cost = 10
	dna_cost = -1

/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
	if(!..())
		return
	var/datum/changeling/changeling = user.mind.changeling
	var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
	if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
		user << "We have reached our capacity to store genetic information! We must transform before absorbing more."
		return
	return 1

/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
	var/datum/changeling/changeling = user.mind.changeling
	var/list/names = list()
	for(var/datum/changelingprofile/prof in hivemind_bank)
		if(!(prof in changeling.stored_profiles))
			names[prof.name] = prof

	if(names.len <= 0)
		user << "There's no new DNA to absorb from the air."
		return

	var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
	if(!S)
		return
	var/datum/changelingprofile/chosen_prof = names[S]
	if(!chosen_prof)
		return

	var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
	chosen_prof.copy_profile(downloaded_prof)
	changeling.add_profile(downloaded_prof)
	user << "We absorb the DNA of [S] from the air."
	feedback_add_details("changeling_powers","HD")
	return 1


code:
/obj/effect/proc_holder/changeling/humanform
	name = "Human form"
	desc = "We change into a human."
	chemical_cost = 5
	genetic_damage = 3
	req_dna = 1
	max_genetic_damage = 3

//Transform into a human.
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
	var/datum/changeling/changeling = user.mind.changeling
	var/list/names = list()
	for(var/datum/changelingprofile/prof in changeling.stored_profiles)
		names += "[prof.name]"

	var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
	if(!chosen_name)
		return

	var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
	if(!chosen_prof)
		return
	if(!user || user.notransform)
		return 0
	user << "We transform our appearance."

	changeling.purchasedpowers -= src

	var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)

	changeling_transform(newmob, chosen_prof)
	feedback_add_details("changeling_powers","LFT")
	return 1


code:
/obj/effect/proc_holder/changeling/lesserform
	name = "Lesser form"
	desc = "We debase ourselves and become lesser. We become a monkey."
	chemical_cost = 5
	dna_cost = 1
	genetic_damage = 3
	req_human = 1

//Transform into a monkey.
/obj/effect/proc_holder/changeling/lesserform/sting_action(mob/living/carbon/human/user)
	if(!user || user.notransform)
		return 0
	user << "Our genes cry out!"

	user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)

	feedback_add_details("changeling_powers","LF")
	return 1


code:
/obj/effect/proc_holder/changeling/mimicvoice
	name = "Mimic Voice"
	desc = "We shape our vocal glands to sound like a desired voice."
	helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this."
	chemical_cost = 0 //constant chemical drain hardcoded
	dna_cost = 1
	req_human = 1

// Fake Voice
/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
	var/datum/changeling/changeling=user.mind.changeling
	if(changeling.mimicing)
		changeling.mimicing = ""
		changeling.chem_recharge_slowdown -= 0.5
		user << "We return our vocal glands to their original position."
		return

	var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
	if(!mimic_voice)
		return

	changeling.mimicing = mimic_voice
	changeling.chem_recharge_slowdown += 0.5
	user << "We shape our glands to take the voice of [mimic_voice], this will slow down regenerating chemicals while active."
	user << "Use this power again to return to our original voice and return chemical production to normal levels."

	feedback_add_details("changeling_powers","MV")


code:
/*
	Changeling Mutations! ~By Miauw (ALL OF IT :V)
	Contains:
		Arm Blade
		Space Suit
		Shield
		Armor
*/

//Parent to shields and blades because muh copypasted code.
/obj/effect/proc_holder/changeling/weapon
	name = "Organic Weapon"
	desc = "Go tell a coder if you see this"
	helptext = "Yell at Miauw and/or Perakp"
	chemical_cost = 1000
	dna_cost = -1
	genetic_damage = 1000

	var/weapon_type
	var/weapon_name_simple

/obj/effect/proc_holder/changeling/weapon/try_to_sting(mob/user, mob/target)
	if(check_weapon(user, user.r_hand, 1))
		return
	if(check_weapon(user, user.l_hand, 0))
		return
	..(user, target)

/obj/effect/proc_holder/changeling/weapon/proc/check_weapon(mob/user, obj/item/hand_item, right_hand=1)
	if(istype(hand_item, weapon_type))
		playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
		qdel(hand_item)
		user.visible_message("With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "You hear organic matter ripping and tearing!")
		if(right_hand)
			user.update_inv_r_hand()
		else
			user.update_inv_l_hand()
		return 1

/obj/effect/proc_holder/changeling/weapon/sting_action(mob/user)
	if(!user.drop_item())
		user << "The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!"
		return
	var/obj/item/W = new weapon_type(user)
	user.put_in_hands(W)
	playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
	return W

/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user)
	check_weapon(user, user.r_hand, 1)
	check_weapon(user, user.l_hand, 0)

//Parent to space suits and armor.
/obj/effect/proc_holder/changeling/suit
	name = "Organic Suit"
	desc = "Go tell a coder if you see this"
	helptext = "Yell at Miauw and/or Perakp"
	chemical_cost = 1000
	dna_cost = -1
	genetic_damage = 1000

	var/helmet_type = /obj/item
	var/suit_type = /obj/item
	var/suit_name_simple = "    "
	var/helmet_name_simple = "     "
	var/recharge_slowdown = 0
	var/blood_on_castoff = 0

/obj/effect/proc_holder/changeling/suit/try_to_sting(mob/user, mob/target)
	if(check_suit(user))
		return
	var/mob/living/carbon/human/H = user
	..(H, target)

//checks if we already have an organic suit and casts it off.
/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user)
	var/datum/changeling/changeling = user.mind.changeling
	if(!ishuman(user) || !changeling)
		return 1
	var/mob/living/carbon/human/H = user
	if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type))
		H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!")
		qdel(H.wear_suit)
		qdel(H.head)
		H.update_inv_wear_suit()
		H.update_inv_head()
		H.update_hair()

		if(blood_on_castoff)
			var/turf/T = get_turf(H)
			if(istype(T))
				T.add_blood(H) //So real blood decals
				playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds

		changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds.
		changeling.chem_recharge_slowdown -= recharge_slowdown
		return 1

/obj/effect/proc_holder/changeling/suit/on_refund(mob/user)
	if(!ishuman(user))
		return
	var/mob/living/carbon/human/H = user
	check_suit(H)

/obj/effect/proc_holder/changeling/suit/sting_action(mob/living/carbon/human/user)
	if(!user.canUnEquip(user.wear_suit))
		user << "\the [user.wear_suit] is stuck to your body, you cannot grow a [suit_name_simple] over it!"
		return
	if(!user.canUnEquip(user.head))
		user << "\the [user.head] is stuck on your head, you cannot grow a [helmet_name_simple] over it!"
		return

	user.unEquip(user.head)
	user.unEquip(user.wear_suit)

	user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1)
	user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1)

	var/datum/changeling/changeling = user.mind.changeling
	changeling.chem_recharge_slowdown += recharge_slowdown
	return 1

//fancy headers yo
/***************************************\
|***************ARM BLADE***************|
\***************************************/
/obj/effect/proc_holder/changeling/weapon/arm_blade
	name = "Arm Blade"
	desc = "We reform one of our arms into a deadly blade."
	helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form."
	chemical_cost = 20
	dna_cost = 2
	genetic_damage = 10
	req_human = 1
	max_genetic_damage = 20
	weapon_type = /obj/item/weapon/melee/arm_blade
	weapon_name_simple = "blade"

/obj/item/weapon/melee/arm_blade
	name = "arm blade"
	desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter"
	icon = 'icons/obj/weapons.dmi'
	icon_state = "arm_blade"
	item_state = "arm_blade"
	flags = ABSTRACT | NODROP
	w_class = 5.0
	force = 25
	throwforce = 0 //Just to be on the safe side
	throw_range = 0
	throw_speed = 0
	sharpness = IS_SHARP

/obj/item/weapon/melee/arm_blade/New(location,silent)
	..()
	if(ismob(loc) && !silent)
		loc.visible_message("A grotesque blade forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!")

/obj/item/weapon/melee/arm_blade/dropped(mob/user)
	qdel(src)

/obj/item/weapon/melee/arm_blade/afterattack(atom/target, mob/user, proximity)
	if(!proximity)
		return
	if(istype(target, /obj/structure/table))
		var/obj/structure/table/T = target
		T.table_destroy(1)

	else if(istype(target, /obj/machinery/computer))
		var/obj/machinery/computer/C = target
		C.attack_alien(user) //muh copypasta

	else if(istype(target, /obj/machinery/door/airlock))
		var/obj/machinery/door/airlock/A = target

		if(!A.requiresID() || A.allowed(user)) //This is to prevent stupid shit like hitting a door with an arm blade, the door opening because you have acces and still getting a "the airlocks motors resist our efforts to force it" message.
			return

		if(A.hasPower())
			if(A.locked)
				user << "The airlock's bolts prevent it from being forced!"
				return
			user << "The airlock's motors are resisting, this may take time..."
			if(do_after(user, 100, target = A))
				A.open(2)
			return

		else if(A.locked)
			user << "The airlock's bolts prevent it from being forced!"
			return

		else
			//user.say("Heeeeeeeeeerrre's Johnny!")
			user.visible_message("[user] forces the door to open with \his [src]!", "We force the door to open.", "You hear a metal screeching sound.")
			A.open(1)

/***************************************\
|****************SHIELD*****************|
\***************************************/
/obj/effect/proc_holder/changeling/weapon/shield
	name = "Organic Shield"
	desc = "We reform one of our arms into a hard shield."
	helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form."
	chemical_cost = 20
	dna_cost = 1
	genetic_damage = 12
	req_human = 1
	max_genetic_damage = 20

	weapon_type = /obj/item/weapon/shield/changeling
	weapon_name_simple = "shield"

/obj/effect/proc_holder/changeling/weapon/shield/sting_action(mob/user)
	var/datum/changeling/changeling = user.mind.changeling //So we can read the absorbedcount.
	if(!changeling)
		return

	var/obj/item/weapon/shield/changeling/S = ..(user)
	S.remaining_uses = round(changeling.absorbedcount * 3)
	return 1

/obj/item/weapon/shield/changeling
	name = "shield-like mass"
	desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield."
	flags = ABSTRACT | NODROP
	icon = 'icons/obj/weapons.dmi'
	icon_state = "ling_shield"
	block_chance = 50

	var/remaining_uses //Set by the changeling ability.

/obj/item/weapon/shield/changeling/New()
	..()
	if(ismob(loc))
		loc.visible_message("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!", "We inflate our hand into a strong shield.", "You hear organic matter ripping and tearing!")

/obj/item/clothing/head/helmet/space/changeling/dropped()
	qdel(src)

/obj/item/weapon/shield/changeling/hit_reaction()
	if(remaining_uses < 1)
		if(ishuman(loc))
			var/mob/living/carbon/human/H = loc
			H.visible_message("With a sickening crunch, [H] reforms his shield into an arm!", "We assimilate our shield into our body", "You hear organic matter ripping and tearing!")
			H.unEquip(src, 1)
		qdel(src)
		return 0
	else
		remaining_uses--
		return ..()

/***************************************\
|*********SPACE SUIT + HELMET***********|
\***************************************/
/obj/effect/proc_holder/changeling/suit/organic_space_suit
	name = "Organic Space Suit"
	desc = "We grow an organic suit to protect ourselves from space exposure."
	helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Retreating the suit damages our genomes. Cannot be used in lesser form."
	chemical_cost = 20
	dna_cost = 2
	genetic_damage = 8
	req_human = 1
	max_genetic_damage = 20

	suit_type = /obj/item/clothing/suit/space/changeling
	helmet_type = /obj/item/clothing/head/helmet/space/changeling
	suit_name_simple = "flesh shell"
	helmet_name_simple = "space helmet"
	recharge_slowdown = 0.5
	blood_on_castoff = 1

/obj/item/clothing/suit/space/changeling
	name = "flesh mass"
	icon_state = "lingspacesuit"
	desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel."
	flags = STOPSPRESSUREDMAGE | NODROP //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff)
	allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank/internals/emergency_oxygen, /obj/item/weapon/tank/internals/oxygen)
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) //No armor at all.

/obj/item/clothing/suit/space/changeling/New()
	..()
	if(ismob(loc))
		loc.visible_message("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around their body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!")
	SSobj.processing += src

/obj/item/clothing/suit/space/changeling/dropped()
	qdel(src)

/obj/item/clothing/suit/space/changeling/process()
	if(ishuman(loc))
		var/mob/living/carbon/human/H = loc
		H.reagents.add_reagent("salbutamol", REAGENTS_METABOLISM)

/obj/item/clothing/head/helmet/space/changeling
	name = "flesh mass"
	icon_state = "lingspacehelmet"
	desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front."
	flags = STOPSPRESSUREDMAGE | NODROP //Again, no THICKMATERIAL.
	armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
	flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH

/obj/item/clothing/head/helmet/space/changeling/dropped()
	qdel(src)

/***************************************\
|*****************ARMOR*****************|
\***************************************/
/obj/effect/proc_holder/changeling/suit/armor
	name = "Chitinous Armor"
	desc = "We turn our skin into tough chitin to protect us from damage."
	helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form."
	chemical_cost = 20
	dna_cost = 1
	genetic_damage = 11
	req_human = 1
	max_genetic_damage = 20
	recharge_slowdown = 0.25

	suit_type = /obj/item/clothing/suit/armor/changeling
	helmet_type = /obj/item/clothing/head/helmet/changeling
	suit_name_simple = "armor"
	helmet_name_simple = "helmet"

/obj/item/clothing/suit/armor/changeling
	name = "chitinous mass"
	desc = "A tough, hard covering of black chitin."
	icon_state = "lingarmor"
	flags = NODROP
	body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
	armor = list(melee = 40, bullet = 40, laser = 40, energy = 20, bomb = 10, bio = 4, rad = 0)
	flags_inv = HIDEJUMPSUIT
	cold_protection = 0
	heat_protection = 0

/obj/item/clothing/suit/armor/changeling/New()
	..()
	if(ismob(loc))
		loc.visible_message("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!", "We harden our flesh, creating a suit of armor!", "You hear organic matter ripping and tearing!")

/obj/item/clothing/suit/armor/changeling/dropped()
	qdel(src)

/obj/item/clothing/head/helmet/changeling
	name = "chitinous mass"
	desc = "A tough, hard covering of black chitin with transparent chitin in front."
	icon_state = "lingarmorhelmet"
	flags = NODROP
	armor = list(melee = 30, bullet = 30, laser = 40, energy = 20, bomb = 10, bio = 4, rad = 0)
	flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE

/obj/item/clothing/head/helmet/changeling/dropped()
	qdel(src)


code:
/obj/effect/proc_holder/changeling/panacea
	name = "Anatomic Panacea"
	desc = "Expels impurifications from our form; curing diseases, removing parasites, sobering us, purging toxins and radiation, and resetting our genetic code completely."
	helptext = "Can be used while unconscious."
	chemical_cost = 20
	dna_cost = 1
	req_stat = UNCONSCIOUS

//Heals the things that the other regenerative abilities don't.
/obj/effect/proc_holder/changeling/panacea/sting_action(mob/user)
	user << "We begin cleansing impurities from our form."

	var/obj/item/organ/internal/body_egg/egg = user.getorgan(/obj/item/organ/internal/body_egg)
	if(egg)
		egg.Remove(user)
		if(iscarbon(user))
			var/mob/living/carbon/C = user
			C.vomit(0)
		egg.loc = get_turf(user)

	user.reagents.add_reagent("mutadone", 10)
	user.reagents.add_reagent("potass_iodide", 10)
	user.reagents.add_reagent("charcoal", 20)
	user.reagents.add_reagent("antihol", 10)

	for(var/datum/disease/D in user.viruses)
		D.cure()
	feedback_add_details("changeling_powers","AP")
	return 1


code:
/obj/effect/proc_holder/changeling/revive
	name = "Regenerate"
	desc = "We regenerate, healing all damage from our form."
	req_stat = DEAD

//Revive from revival stasis
/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
	user.status_flags &= ~(FAKEDEATH)
	user.tod = null
	user.revive(full_heal = 1)
	user << "We have regenerated."
	user.mind.changeling.purchasedpowers -= src
	feedback_add_details("changeling_powers","CR")
	return 1

/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
	if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
		user.mind.changeling.purchasedpowers -= src
		return 0
	. = ..()


code:
/obj/effect/proc_holder/changeling/resonant_shriek
	name = "Resonant Shriek"
	desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
	helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors."
	chemical_cost = 20
	dna_cost = 1
	req_human = 1

//A flashy ability, good for crowd control and sewing chaos.
/obj/effect/proc_holder/changeling/resonant_shriek/sting_action(mob/user)
	for(var/mob/living/M in get_hearers_in_view(4, user))
		if(iscarbon(M))
			if(!M.mind || !M.mind.changeling)
				M.adjustEarDamage(0,30)
				M.confused += 25
				M.Jitter(50)
			else
				M << sound('sound/effects/screech.ogg')

		if(issilicon(M))
			M << sound('sound/weapons/flash.ogg')
			M.Weaken(rand(5,10))

	for(var/obj/machinery/light/L in range(4, user))
		L.on = 1
		L.broken()

	feedback_add_details("changeling_powers","RS")
	return 1

/obj/effect/proc_holder/changeling/dissonant_shriek
	name = "Dissonant Shriek"
	desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics."
	chemical_cost = 20
	dna_cost = 1

//A flashy ability, good for crowd control and sewing chaos.
/obj/effect/proc_holder/changeling/dissonant_shriek/sting_action(mob/user)
	for(var/obj/machinery/light/L in range(5, usr))
		L.on = 1
		L.broken()
	empulse(get_turf(user), 2, 5, 1)
	return 1


code:
/obj/effect/proc_holder/changeling/spiders
	name = "Spread Infestation"
	desc = "Our form divides, creating arachnids which will grow into deadly beasts."
	helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 DNA absorptions."
	chemical_cost = 45
	dna_cost = 1
	req_dna = 5

//Makes some spiderlings. Good for setting traps and causing general trouble.
/obj/effect/proc_holder/changeling/spiders/sting_action(mob/user)
	for(var/i=0, i<2, i++)
		var/obj/effect/spider/spiderling/S = new(user.loc)
		S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter

	feedback_add_details("changeling_powers","SI")
	return 1


code:
//Strained Muscles: Temporary speed boost at the cost of rapid damage
//Limited because of hardsuits and such; ideally, used for a quick getaway

/obj/effect/proc_holder/changeling/strained_muscles
	name = "Strained Muscles"
	desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster."
	helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form."
	chemical_cost = 0
	dna_cost = 1
	req_human = 1
	var/stacks = 0 //Increments every 5 seconds; damage increases over time
	var/active = 0 //Whether or not you are a hedgehog

/obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user)
	active = !active
	if(active)
		user << "Our muscles tense and strengthen."
	else
		user.status_flags -= GOTTAGOFAST
		user << "Our muscles relax."
		if(stacks >= 10)
			user << "We collapse in exhaustion."
			user.Weaken(3)
			user.emote("gasp")

	while(active)
		user.status_flags |= GOTTAGOFAST
		if(user.stat != CONSCIOUS || user.staminaloss >= 90)
			active = !active
			user << "Our muscles relax without the energy to strengthen them."
			user.Weaken(2)
			user.status_flags -= GOTTAGOFAST
			break

		stacks++
		//user.take_organ_damage(stacks * 0.03, 0)
		user.staminaloss += stacks * 1.3 //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack

		if(stacks == 11) //Warning message that the stacks are getting too high
			user << "Our legs are really starting to hurt..."

		sleep(40)

	while(!active) //Damage stacks decrease fairly rapidly while not in sanic mode
		if(stacks >= 1)
			stacks--
		sleep(20)

	feedback_add_details("changeling_powers","SANIC")
	return 1


code:
/obj/effect/proc_holder/changeling/sting
	name = "Tiny Prick"
	desc = "Stabby stabby"
	var/sting_icon = null

/obj/effect/proc_holder/changeling/sting/Click()
	var/mob/user = usr
	if(!user || !user.mind || !user.mind.changeling)
		return
	if(!(user.mind.changeling.chosen_sting))
		set_sting(user)
	else
		unset_sting(user)
	return

/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user)
	user << "We prepare our sting, use alt+click or middle mouse button on target to sting them."
	user.mind.changeling.chosen_sting = src
	user.hud_used.lingstingdisplay.icon_state = sting_icon
	user.hud_used.lingstingdisplay.invisibility = 0

/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user)
	user << "We retract our sting, we can't sting anyone for now."
	user.mind.changeling.chosen_sting = null
	user.hud_used.lingstingdisplay.icon_state = null
	user.hud_used.lingstingdisplay.invisibility = 101

/mob/living/carbon/proc/unset_sting()
	if(mind && mind.changeling && mind.changeling.chosen_sting)
		src.mind.changeling.chosen_sting.unset_sting(src)

/obj/effect/proc_holder/changeling/sting/can_sting(mob/user, mob/target)
	if(!..())
		return
	if(!user.mind.changeling.chosen_sting)
		user << "We haven't prepared our sting yet!"
	if(!iscarbon(target))
		return
	if(!isturf(user.loc))
		return
	if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
		return
	if(target.mind && target.mind.changeling)
		sting_feedback(user,target)
		take_chemical_cost(user.mind.changeling)
		return
	return 1

/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
	if(!target)
		return
	user << "We stealthily sting [target.name]."
	if(target.mind && target.mind.changeling)
		target << "You feel a tiny prick."
	return 1

/obj/effect/proc_holder/changeling/sting/transformation
	name = "Transformation Sting"
	desc = "We silently sting a human, injecting a retrovirus that forces them to transform."
	helptext = "The victim will transform much like a changeling would. The effects will be obvious to the victim, and the process will damage our genomes."
	sting_icon = "sting_transform"
	chemical_cost = 40
	dna_cost = 3
	genetic_damage = 100
	var/datum/changelingprofile/selected_dna = null

/obj/effect/proc_holder/changeling/sting/transformation/Click()
	var/mob/user = usr
	var/datum/changeling/changeling = user.mind.changeling
	if(changeling.chosen_sting)
		unset_sting(user)
		return
	selected_dna = changeling.select_dna("Select the target DNA: ", "Target DNA")
	if(!selected_dna)
		return
	if(NOTRANSSTING in selected_dna.dna.species.specflags)
		user << "That DNA is not compatible with changeling retrovirus!"
		return
	..()

/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/target)
	if(!..())
		return
	if((target.disabilities & HUSK) || !target.has_dna())
		user << "Our sting appears ineffective against its DNA."
		return 0
	return 1

/obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target)
	add_logs(user, target, "stung", "transformation sting", " new identity is [selected_dna.dna.real_name]")
	var/datum/dna/NewDNA = selected_dna.dna
	if(ismonkey(target))
		user << "Our genes cry out as we sting [target.name]!"

	if(iscarbon(target))
		var/mob/living/carbon/C = target
		if(C.status_flags & CANWEAKEN)
			C.do_jitter_animation(500)
			C.take_organ_damage(20, 0) //The process is extremely painful

		target.visible_message("[target] begins to violenty convulse!","You feel a tiny prick and a begin to uncontrollably convulse!")
		spawn(10)
			C.real_name = NewDNA.real_name
			NewDNA.transfer_identity(C, transfer_SE=1)
			C.updateappearance(mutcolor_update=1)
			C.domutcheck()
	feedback_add_details("changeling_powers","TS")
	return 1

/obj/effect/proc_holder/changeling/sting/false_armblade
	name = "False Armblade Sting"
	desc = "We silently sting a human, injecting a retrovirus that mutates their arm to temporarily appear as an armblade."
	helptext = "The victim will form an armblade much like a changeling would, except the armblade is dull and useless."
	sting_icon = "sting_armblade"
	chemical_cost = 20
	dna_cost = 1
	genetic_damage = 20
	max_genetic_damage = 10

/obj/item/weapon/melee/arm_blade/false
	desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless."
	force = 5 //Basically as strong as a punch

/obj/item/weapon/melee/arm_blade/false/afterattack(atom/target, mob/user, proximity)
	return

/obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target)
	if(!..())
		return
	if((target.disabilities & HUSK) || !target.has_dna())
		user << "Our sting appears ineffective against its DNA."
		return 0
	return 1

/obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target)
	add_logs(user, target, "stung", object="falso armblade sting")

	if(!target.drop_item())
		user << "The [target.get_active_hand()] is stuck to their hand, you cannot grow a false armblade over it!"
		return

	if(ismonkey(target))
		user << "Our genes cry out as we sting [target.name]!"

	var/obj/item/weapon/melee/arm_blade/false/blade = new(target,1)
	target.put_in_hands(blade)
	target.visible_message("A grotesque blade forms around [target.name]\'s arm!", "Your arm twists and mutates, transforming into a horrific monstrosity!", "You hear organic matter ripping and tearing!")
	playsound(target, 'sound/effects/blobattack.ogg', 30, 1)

	spawn(600)
		playsound(target, 'sound/effects/blobattack.ogg', 30, 1)
		target.visible_message("With a sickening crunch, [target] reforms their [blade.name] into an arm!", "[blade] reforms back to normal.", "You hear organic matter ripping and tearing!")
		qdel(blade)
		user.update_inv_l_hand()
		user.update_inv_r_hand()

	feedback_add_details("changeling_powers","AS")
	return 1

/obj/effect/proc_holder/changeling/sting/extract_dna
	name = "Extract DNA Sting"
	desc = "We stealthily sting a target and extract their DNA."
	helptext = "Will give you the DNA of your target, allowing you to transform into them."
	sting_icon = "sting_extract"
	chemical_cost = 25
	dna_cost = 0

/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
	if(..())
		return user.mind.changeling.can_absorb_dna(user, target)

/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
	add_logs(user, target, "stung", "extraction sting")
	if(!(user.mind.changeling.has_dna(target.dna)))
		user.mind.changeling.add_new_profile(target, user)
	feedback_add_details("changeling_powers","ED")
	return 1

/obj/effect/proc_holder/changeling/sting/mute
	name = "Mute Sting"
	desc = "We silently sting a human, completely silencing them for a short time."
	helptext = "Does not provide a warning to the victim that they have been stung, until they try to speak and cannot."
	sting_icon = "sting_mute"
	chemical_cost = 20
	dna_cost = 2

/obj/effect/proc_holder/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target)
	add_logs(user, target, "stung", "mute sting")
	target.silent += 30
	feedback_add_details("changeling_powers","MS")
	return 1

/obj/effect/proc_holder/changeling/sting/blind
	name = "Blind Sting"
	desc = "Temporarily blinds the target."
	helptext = "This sting completely blinds a target for a short time."
	sting_icon = "sting_blind"
	chemical_cost = 25
	dna_cost = 1

/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
	add_logs(user, target, "stung", "blind sting")
	target << "Your eyes burn horrifically!"
	target.become_nearsighted()
	target.blind_eyes(20)
	target.blur_eyes(40)
	feedback_add_details("changeling_powers","BS")
	return 1

/obj/effect/proc_holder/changeling/sting/LSD
	name = "Hallucination Sting"
	desc = "Causes terror in the target."
	helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect occurs after 30 to 60 seconds."
	sting_icon = "sting_lsd"
	chemical_cost = 10
	dna_cost = 1

/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/living/carbon/target)
	add_logs(user, target, "stung", "LSD sting")
	spawn(rand(300,600))
		if(target)
			target.hallucination = max(400, target.hallucination)
	feedback_add_details("changeling_powers","HS")
	return 1

/obj/effect/proc_holder/changeling/sting/cryo
	name = "Cryogenic Sting"
	desc = "We silently sting a human with a cocktail of chemicals that freeze them."
	helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing."
	sting_icon = "sting_cryo"
	chemical_cost = 15
	dna_cost = 2

/obj/effect/proc_holder/changeling/sting/cryo/sting_action(mob/user, mob/target)
	add_logs(user, target, "stung", "cryo sting")
	if(target.reagents)
		target.reagents.add_reagent("frostoil", 30)
	feedback_add_details("changeling_powers","CS")
	return 1


code:
/obj/effect/proc_holder/changeling/transform
	name = "Transform"
	desc = "We take on the appearance and voice of one we have absorbed."
	chemical_cost = 5
	dna_cost = 0
	req_dna = 1
	req_human = 1
	max_genetic_damage = 3

/obj/item/clothing/glasses/changeling
	name = "flesh"
	flags = NODROP

/obj/item/clothing/under/changeling
	name = "flesh"
	flags = NODROP

/obj/item/clothing/suit/changeling
	name = "flesh"
	flags = NODROP
	allowed = list(/obj/item/changeling)

/obj/item/clothing/head/changeling
	name = "flesh"
	flags = NODROP
/obj/item/clothing/shoes/changeling
	name = "flesh"
	flags = NODROP

/obj/item/clothing/gloves/changeling
	name = "flesh"
	flags = NODROP

/obj/item/clothing/mask/changeling
	name = "flesh"
	flags = NODROP

/obj/item/changeling
	name = "flesh"
	flags = NODROP
	slot_flags = ALL
	allowed = list(/obj/item/changeling)

//Change our DNA to that of somebody we've absorbed.
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
	var/datum/changeling/changeling = user.mind.changeling
	var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA", user)

	if(!chosen_prof)
		return

	changeling_transform(user, chosen_prof)

	feedback_add_details("changeling_powers","TR")
	return 1

/datum/changeling/proc/select_dna(var/prompt, var/title, var/mob/living/carbon/user)
	var/list/names = list("Drop Flesh Disguise")
	for(var/datum/changelingprofile/prof in stored_profiles)
		names += "[prof.name]"

	var/chosen_name = input(prompt, title, null) as null|anything in names
	if(!chosen_name)
		return

	if(chosen_name == "Drop Flesh Disguise")
		for(var/slot in slots)
			if(istype(user.vars[slot], slot2type[slot]))
				qdel(user.vars[slot])

	var/datum/changelingprofile/prof = get_dna(chosen_name)
	return prof


code:
/datum/game_mode/traitor/changeling
	name = "traitor+changeling"
	config_tag = "traitorchan"
	traitors_possible = 3 //hard limit on traitors if scaling is turned off
	restricted_jobs = list("AI", "Cyborg")
	required_players = 0
	required_enemies = 1	// how many of each type are required
	recommended_enemies = 3
	reroll_friendly = 1

	var/list/possible_changelings = list()
	var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off

/datum/game_mode/traitor/changeling/announce()
	world << "The current game mode is - Traitor+Changeling!"
	world << "There are alien creatures on the station along with some syndicate operatives out for their own gain! Do not let the changelings or the traitors succeed!"

/datum/game_mode/traitor/changeling/can_start()
	if(!..())
		return 0
	possible_changelings = get_players_for_role(ROLE_CHANGELING)
	if(possible_changelings.len < required_enemies)
		return 0
	return 1

/datum/game_mode/traitor/changeling/pre_setup()
	if(config.protect_roles_from_antagonist)
		restricted_jobs += protected_jobs

	if(config.protect_assistant_from_antagonist)
		restricted_jobs += "Assistant"

	var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)

	var/num_changelings = 1

	if(config.changeling_scaling_coeff)
		num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) ))
	else
		num_changelings = max(1, min(num_players(), changeling_amount/2))

	if(possible_changelings.len>0)
		for(var/j = 0, j < num_changelings, j++)
			if(!possible_changelings.len) break
			var/datum/mind/changeling = pick(possible_changelings)
			possible_changelings -= changeling
			changelings += changeling
			modePlayer += changelings
			changeling.restricted_roles = restricted_jobs
		return ..()
	else
		return 0

/datum/game_mode/traitor/changeling/post_setup()
	for(var/datum/mind/changeling in changelings)
		changeling.current.make_changeling(changeling.current)
		changeling.special_role = "Changeling"
		forge_changeling_objectives(changeling)
		greet_changeling(changeling)
	..()
	return

/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
	var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(joined_player_list.len/(config.changeling_scaling_coeff*2)) )
	if(ticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
		..()
		return
	if(ticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
		if(ROLE_CHANGELING in character.client.prefs.be_special)
			if(!jobban_isbanned(character.client, ROLE_CHANGELING) && !jobban_isbanned(character.client, "Syndicate"))
				if(age_check(character.client))
					if(!(character.job in restricted_jobs))
						character.mind.make_Changling()
	..()


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

/datum/game_mode
	var/list/datum/mind/cult = list()
	var/list/cult_objectives = list()

/proc/iscultist(mob/living/M)
	return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult)

/proc/is_sacrifice_target(datum/mind/mind)
	if(ticker.mode.name == "cult")
		var/datum/game_mode/cult/cult_mode = ticker.mode
		if(mind == cult_mode.sacrifice_target)
			return 1
	return 0

/proc/is_convertable_to_cult(datum/mind/mind)
	if(!istype(mind))	return 0
	if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain")))	return 0
	if(isloyal(mind.current))
		return 0
	if (ticker.mode.name == "cult")		//redundant?
		if(is_sacrifice_target(mind))	return 0
	return 1

/proc/cultist_commune(mob/living/user, clear = 0, say = 0, message)
	if(!message)
		return
	if(say)
		user.say("O bidai nabora se[pick("'","`")]sma!")
	else
		user.whisper("O bidai nabora se[pick("'","`")]sma!")
	sleep(10)
	if(!user)
		return
	if(say)
		user.say(message)
	else
		user.whisper(message)
	var/my_message = "Error, message null. You should probably report this."
	for(var/mob/M in mob_list)
		if(iscultist(M) || (M in dead_mob_list))
			if(clear || !ishuman(user))
				my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]"
			else //Emergency comms
				my_message = "Acolyte ???: [message]"
			if(M in dead_mob_list)
				M << "(F) [my_message]"
			else
				M << my_message

	log_say("[user.real_name]/[user.key] : [message]")

/datum/game_mode/cult
	name = "cult"
	config_tag = "cult"
	antag_flag = ROLE_CULTIST
	restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
	protected_jobs = list()
	required_players = 30
	required_enemies = 4
	recommended_enemies = 4
	enemy_minimum_age = 14

	var/finished = 0
	var/eldergod = 1 //for the summon god objective

	var/acolytes_needed = 10 //for the survive objective
	var/acolytes_survived = 0

	var/datum/mind/sacrifice_target = null//The target to be sacrificed

/datum/game_mode/cult/announce()
	world << "The current game mode is - Cult!"
	world << "Some crewmembers are attempting to start a cult!
\nCultists - complete your objectives at all costs. Convert crewmembers to your cause by using the convert rune, or sacrifice them and turn them into constructs. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Forced consumption of holy water will convert a cultist back to a Nanotrasen-sanctioned faith."

/datum/game_mode/cult/pre_setup()
	cult_objectives += "sacrifice"
	cult_objectives += "eldergod"

	if(config.protect_roles_from_antagonist)
		restricted_jobs += protected_jobs

	if(config.protect_assistant_from_antagonist)
		restricted_jobs += "Assistant"

	//cult scaling goes here
	recommended_enemies = 3 + round(num_players()/20)

	for(var/cultists_number = 1 to recommended_enemies)
		if(!antag_candidates.len)
			break
		var/datum/mind/cultist = pick(antag_candidates)
		antag_candidates -= cultist
		cult += cultist
		cultist.special_role = "Cultist"
		cultist.restricted_roles = restricted_jobs
		log_game("[cultist.key] (ckey) has been selected as a cultist")

	return (cult.len>=required_enemies)

/datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind)
	for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++)
		var/explanation
		switch(cult_objectives[obj_count])
			if("survive")
				explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
			if("sacrifice")
				if(sacrifice_target)
					explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so."
				else
					explanation = "Free objective."
			if("eldergod")
				explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it."
		cult_mind.current << "Objective #[obj_count]: [explanation]"
		cult_mind.memory += "Objective #[obj_count]: [explanation]
"
/datum/game_mode/cult/post_setup()
	modePlayer += cult
	if("sacrifice" in cult_objectives)
		var/list/possible_targets = get_unconvertables()
		if(!possible_targets.len)
			message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.")
			for(var/mob/living/carbon/human/player in player_list)
				if(player.mind && !(player.mind in cult))
					possible_targets += player.mind
		if(possible_targets.len > 0)
			sacrifice_target = pick(possible_targets)
			if(!sacrifice_target)
				message_admins("Cult Sacrifice: ERROR -  Null target chosen!")
		else
			message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
	for(var/datum/mind/cult_mind in cult)
		equip_cultist(cult_mind.current)
		update_cult_icons_added(cult_mind)
		cult_mind.current << "You are a member of the cult!"
		memorize_cult_objectives(cult_mind)
	..()
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob,tome = 0)
	if(!istype(mob))
		return
	mob.cult_add_comm()
	if (mob.mind)
		if (mob.mind.assigned_role == "Clown")
			mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
			mob.dna.remove_mutation(CLOWNMUT)

	if(tome)
		. += cult_give_item(/obj/item/weapon/tome, mob)
	else
		. += cult_give_item(/obj/item/weapon/paper/talisman/supply, mob)
	mob << "These will help you start the cult on this station. Use them well, and remember - you are not the only one."

/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob)
	var/list/slots = list(
		"backpack" = slot_in_backpack,
		"left pocket" = slot_l_store,
		"right pocket" = slot_r_store,
		"left hand" = slot_l_hand,
		"right hand" = slot_r_hand,
	)

	var/T = new item_path(mob)
	var/item_name = initial(item_path.name)
	var/where = mob.equip_in_one_of_slots(T, slots)
	if(!where)
		mob << "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1)."
		return 0
	else
		mob << "You have a [item_name] in your [where]."
		mob.update_icons()
		if(where == "backpack")
			var/obj/item/weapon/storage/B = mob.back
			B.orient2hud(mob)
			B.show_to(mob)
		return 1

/datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE
	if (!istype(cult_mind))
		return 0
	if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
		cult_mind.current.Paralyse(5)
		cult += cult_mind
		cult_mind.current.faction |= "cult"
		cult_mind.current.cult_add_comm()
		update_cult_icons_added(cult_mind)
		cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!"
	if(jobban_isbanned(cult_mind.current, ROLE_CULTIST))
		replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST)
	return 1

/datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT
	if (!..(cult_mind))
		return
	memorize_cult_objectives(cult_mind)

/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1)
	if(cult_mind in cult)
		cult -= cult_mind
		cult_mind.current.faction -= "cult"
		cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm
		cult_mind.current.Paralyse(5)
		cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant."
		cult_mind.memory = ""
		update_cult_icons_removed(cult_mind)
		cult_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the cult!"
		if(show_message)
			for(var/mob/M in viewers(cult_mind.current))
				M << "[cult_mind.current] looks like they just reverted to their old faith!"

/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
	var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT]
	culthud.join_hud(cult_mind.current)
	set_antag_hud(cult_mind.current, "cult")

/datum/game_mode/proc/update_cult_icons_removed(datum/mind/cult_mind)
	var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT]
	culthud.leave_hud(cult_mind.current)
	set_antag_hud(cult_mind.current, null)
/datum/game_mode/cult/proc/get_unconvertables()
	var/list/ucs = list()
	for(var/mob/living/carbon/human/player in player_list)
		if(player.mind && !is_convertable_to_cult(player.mind))
			ucs += player.mind
	return ucs
/datum/game_mode/cult/proc/check_cult_victory()
	var/cult_fail = 0
	if(cult_objectives.Find("survive"))
		cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise
	if(cult_objectives.Find("eldergod"))
		cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
	if(cult_objectives.Find("sacrifice"))
		if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail
			cult_fail++
	return cult_fail //if any objectives aren't met, failure

/datum/game_mode/cult/proc/check_survive()
	var/acolytes_survived = 0
	for(var/datum/mind/cult_mind in cult)
		if (cult_mind.current && cult_mind.current.stat != DEAD)
			if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
				acolytes_survived++
	if(acolytes_survived>=acolytes_needed)
		return 0
	else
		return 1

/datum/game_mode/cult/declare_completion()

	if(!check_cult_victory())
		feedback_set_details("round_end_result","win - cult win")
		feedback_set("round_end_result",acolytes_survived)
		world << "The cult has succeeded! Nar-sie has snuffed out another torch in the void!"
	else
		feedback_set_details("round_end_result","loss - staff stopped the cult")
		feedback_set("round_end_result",acolytes_survived)
		world << "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!"

	var/text = ""

	if(cult_objectives.len)
		text += "
The cultists' objectives were:"
		for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++)
			var/explanation
			switch(cult_objectives[obj_count])
				if("survive")
					if(!check_survive())
						explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!"
						feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
					else
						explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail."
						feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
				if("sacrifice")
					if(sacrifice_target)
						if(sacrifice_target in sacrificed)
							explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
							feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
						else if(sacrifice_target && sacrifice_target.current)
							explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
							feedback_add_details("cult_objective","cult_sacrifice|FAIL")
						else
							explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)."
							feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
				if("eldergod")
					if(!eldergod)
						explanation = "Summon Nar-Sie. Success!"
						feedback_add_details("cult_objective","cult_narsie|SUCCESS")
					else
						explanation = "Summon Nar-Sie. Fail."
						feedback_add_details("cult_objective","cult_narsie|FAIL")
			text += "
Objective #[obj_count]: [explanation]"
	world << text
	..()
	return 1

/datum/game_mode/proc/auto_declare_completion_cult()
	if( cult.len || (ticker && istype(ticker.mode,/datum/game_mode/cult)) )
		var/text = "
The cultists were:"
		for(var/datum/mind/cultist in cult)
			text += printplayer(cultist)

		text += "
"

		world << text