code:
/* Cards
 * Contains:
 *		DATA CARD
 *		ID CARD
 *		FINGERPRINT CARD HOLDER
 *		FINGERPRINT CARD
 */

/*
 * DATA CARDS - Used for the teleporter
 */
/obj/item/weapon/card
	name = "card"
	desc = "Does card things."
	icon = 'icons/obj/card.dmi'
	w_class = 1.0

	var/list/files = list(  )

/obj/item/weapon/card/data
	name = "data disk"
	desc = "A disk of data."
	icon_state = "data"
	var/function = "storage"
	var/data = "null"
	var/special = null
	item_state = "card-id"

/obj/item/weapon/card/data/verb/label(t as text)
	set name = "Label Disk"
	set category = "Object"
	set src in usr

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

	if (t)
		src.name = "data disk- '[t]'"
	else
		src.name = "data disk"
	src.add_fingerprint(usr)
	return

/obj/item/weapon/card/data/clown
	name = "\proper the coordinates to clown planet"
	icon_state = "data"
	item_state = "card-id"
	layer = 3
	level = 2
	desc = "This card contains coordinates to the fabled Clown Planet. Handle with care."
	function = "teleporter"
	data = "Clown Land"

/*
 * ID CARDS
 */
/obj/item/weapon/card/emag
	desc = "It's a card with a magnetic strip attached to some circuitry."
	name = "cryptographic sequencer"
	icon_state = "emag"
	item_state = "card-id"
	origin_tech = "magnets=2;syndicate=2"
	flags = NOBLUDGEON

/obj/item/weapon/card/emag/attack()
	return

/obj/item/weapon/card/emag/afterattack(atom/target, mob/user, proximity)
	var/atom/A = target
	if(!proximity) return
	A.emag_act(user)

/obj/item/weapon/card/id
	name = "identification card"
	desc = "A card used to provide ID and determine access across the station."
	icon_state = "id"
	item_state = "card-id"
	var/mining_points = 0 //For redeeming at mining equipment vendors
	var/list/access = list()
	var/registered_name = null // The name registered_name on the card
	slot_flags = SLOT_ID

	var/assignment = null
	var/dorm = 0		// determines if this ID has claimed a dorm already

/obj/item/weapon/card/id/attack_self(mob/user as mob)
	user.visible_message("[user] shows you: \icon[src] [src.name].", \
					"You show \the [src.name].")
	src.add_fingerprint(user)
	return

/obj/item/weapon/card/id/examine(mob/user)
	..()
	if(mining_points)
		user << "There's [mining_points] mining equipment redemption point\s loaded onto this card."

/obj/item/weapon/card/id/GetAccess()
	return access

/obj/item/weapon/card/id/GetID()
	return src

/*
Usage:
update_label()
	Sets the id name to whatever registered_name and assignment is

update_label("John Doe", "Clowny")
	Properly formats the name and occupation and sets the id name to the arguments
*/
/obj/item/weapon/card/id/proc/update_label(var/newname, var/newjob)
	if(newname || newjob)
		name = "[(!newname)	? "identification card"	: "[newname]'s ID Card"][(!newjob) ? "" : " ([newjob])"]"
		return

	name = "[(!registered_name)	? "identification card"	: "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"

/obj/item/weapon/card/id/silver
	desc = "A silver card which shows honour and dedication."
	icon_state = "silver"
	item_state = "silver_id"

/obj/item/weapon/card/id/gold
	desc = "A golden card which shows power and might."
	icon_state = "gold"
	item_state = "gold_id"

/obj/item/weapon/card/id/syndicate
	name = "agent card"
	access = list(access_maint_tunnels, access_syndicate)
	origin_tech = "syndicate=3"

/obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob, proximity)
	if(!proximity) return
	if(istype(O, /obj/item/weapon/card/id))
		var/obj/item/weapon/card/id/I = O
		src.access |= I.access
		if(istype(user, /mob/living) && user.mind)
			if(user.mind.special_role)
				usr << "The card's microscanners activate as you pass it over the ID, copying its access."

/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
	if(!src.registered_name)
		//Stop giving the players unsanitized unputs! You are giving ways for players to intentionally crash clients! -Nodrak
		var t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)),1,26)
		if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/new_player/prefrences.dm
			alert("Invalid name.")
			return
		src.registered_name = t

		var u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")),1,MAX_MESSAGE_LEN)
		if(!u)
			alert("Invalid assignment.")
			src.registered_name = ""
			return
		src.assignment = u
		update_label()
		user << "You successfully forge the ID card."
	else
		..()

/obj/item/weapon/card/id/syndicate_command
	name = "syndicate ID card"
	desc = "An ID straight from the Syndicate."
	registered_name = "Syndicate"
	assignment = "Syndicate Overlord"
	access = list(access_syndicate)

/obj/item/weapon/card/id/captains_spare
	name = "captain's spare ID"
	desc = "The spare ID of the High Lord himself."
	icon_state = "gold"
	item_state = "gold_id"
	registered_name = "Captain"
	assignment = "Captain"
	New()
		var/datum/job/captain/J = new/datum/job/captain
		access = J.get_access()
		..()

/obj/item/weapon/card/id/centcom
	name = "\improper Centcom ID"
	desc = "An ID straight from Cent. Com."
	icon_state = "centcom"
	registered_name = "Central Command"
	assignment = "General"
	New()
		access = get_all_centcom_access()
		..()
/obj/item/weapon/card/id/ert
	name = "\improper Centcom ID"
	desc = "A ERT ID card"
	icon_state = "centcom"
	registered_name = "Emergency Response Team Commander"
	assignment = "Emergency Response Team Commander"
	New() access = get_all_accesses()+get_ert_access("commander")

/obj/item/weapon/card/id/ert/Security
	registered_name = "Security Response Officer"
	assignment = "Security Response Officer"
	New() access = get_all_accesses()+get_ert_access("sec")

/obj/item/weapon/card/id/ert/Engineer
	registered_name = "Engineer Response Officer"
	assignment = "Engineer Response Officer"
	New() access = get_all_accesses()+get_ert_access("eng")

/obj/item/weapon/card/id/ert/Medical
	registered_name = "Medical Response Officer"
	assignment = "Medical Response Officer"
	New() access = get_all_accesses()+get_ert_access("med")

/obj/item/weapon/card/id/prisoner
	name = "prisoner ID card"
	desc = "You are a number, you are not a free man."
	icon_state = "orange"
	item_state = "orange-id"
	assignment = "Prisoner"
	registered_name = "Scum"
	var/goal = 0 //How far from freedom?
	var/points = 0

/obj/item/weapon/card/id/prisoner/attack_self(mob/user as mob)
	usr << "You have accumulated [points] out of the [goal] points you need for freedom."

/obj/item/weapon/card/id/prisoner/one
	name = "Prisoner #13-001"
	registered_name = "Prisoner #13-001"

/obj/item/weapon/card/id/prisoner/two
	name = "Prisoner #13-002"
	registered_name = "Prisoner #13-002"

/obj/item/weapon/card/id/prisoner/three
	name = "Prisoner #13-003"
	registered_name = "Prisoner #13-003"

/obj/item/weapon/card/id/prisoner/four
	name = "Prisoner #13-004"
	registered_name = "Prisoner #13-004"

/obj/item/weapon/card/id/prisoner/five
	name = "Prisoner #13-005"
	registered_name = "Prisoner #13-005"

/obj/item/weapon/card/id/prisoner/six
	name = "Prisoner #13-006"
	registered_name = "Prisoner #13-006"

/obj/item/weapon/card/id/prisoner/seven
	name = "Prisoner #13-007"
	registered_name = "Prisoner #13-007"


code:
#define CHRONO_BEAM_RANGE 3
#define CHRONO_FRAME_COUNT 22
/obj/item/weapon/chrono_eraser
	name = "Timestream Eradication Device"
	desc = "The result of outlawed time-bluespace research, this device is capable of wiping a being from the timestream. They never are, they never were, they never will be."
	icon = 'icons/obj/chronos.dmi'
	icon_state = "chronobackpack"
	item_state = "backpack"
	w_class = 4.0
	slot_flags = SLOT_BACK
	slowdown = 1
	action_button_name = "Equip/Unequip TED Gun"
	var/obj/item/weapon/gun/energy/chrono_gun/PA = null
	var/list/erased_minds = list() //a collection of minds from the dead

/obj/item/weapon/chrono_eraser/proc/pass_mind(var/datum/mind/M)
	erased_minds += M

/obj/item/weapon/chrono_eraser/dropped()
	if(PA)
		qdel(PA)

/obj/item/weapon/chrono_eraser/Destroy()
	dropped()
	..()

/obj/item/weapon/chrono_eraser/ui_action_click()
	var/mob/living/carbon/user = src.loc
	if(iscarbon(user) && (user.back == src))
		if(PA)
			qdel(PA)
		else
			PA = new(src)
			user.put_in_hands(PA)

/obj/item/weapon/gun/energy/chrono_gun
	name = "T.E.D. Projection Apparatus"
	desc = "It's as if they never existed in the first place."
	icon = 'icons/obj/chronos.dmi'
	icon_state = "chronogun"
	item_state = "chronogun"
	w_class = 3.0
	flags = NODROP
	ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam)
	fire_delay = 50
	var/obj/item/weapon/chrono_eraser/TED = null
	var/obj/effect/chrono_field/field = null
	var/turf/startpos = null

/obj/item/weapon/gun/energy/chrono_gun/New(var/obj/item/weapon/chrono_eraser/T)
	. = ..()
	if(istype(T))
		TED = T
	else //admin must have spawned it
		TED = new(src.loc)
		qdel(src)

/obj/item/weapon/gun/energy/chrono_gun/dropped()
	qdel(src)

/obj/item/weapon/gun/energy/chrono_gun/update_icon()
	return

/obj/item/weapon/gun/energy/chrono_gun/process_fire()
	if(field)
		field_disconnect(field)
	..()

/obj/item/weapon/gun/energy/chrono_gun/Destroy()
	if(TED)
		TED.PA = null
		TED = null
	if(field)
		field_disconnect(field)
	..()

/obj/item/weapon/gun/energy/chrono_gun/proc/field_connect(var/obj/effect/chrono_field/F)
	var/mob/living/user = src.loc
	if(F.gun)
		if(isliving(user) && F.captured)
			user << "FAIL: [F.captured] already has an existing connection."
		src.field_disconnect(F)
	else
		startpos = get_turf(src)
		field = F
		F.gun = src
		if(isliving(user) && F.captured)
			user << "Connection established with target: [F.captured]"

/obj/item/weapon/gun/energy/chrono_gun/proc/field_disconnect(var/obj/effect/chrono_field/F)
	if(F && field == F)
		var/mob/living/user = src.loc
		if(F.gun == src)
			F.gun = null
		if(isliving(user) && F.captured)
			user << "Disconnected from target: [F.captured]"
	field = null
	startpos = null

/obj/item/weapon/gun/energy/chrono_gun/proc/field_check(var/obj/effect/chrono_field/F)
	if(F)
		if(field == F)
			var/turf/currentpos = get_turf(src)
			var/mob/living/user = src.loc
			if((currentpos == startpos) && (field in view(CHRONO_BEAM_RANGE, currentpos)) && !user.lying && (user.stat == CONSCIOUS))
				return 1
		field_disconnect(F)
		return 0

/obj/item/weapon/gun/energy/chrono_gun/proc/pass_mind(var/datum/mind/M)
	if(TED)
		TED.pass_mind(M)

/obj/item/projectile/energy/chrono_beam
	name = "eradication beam"
	icon_state = "chronobolt"
	range = CHRONO_BEAM_RANGE
	color = null
	nodamage = 1
	var/obj/item/weapon/gun/energy/chrono_gun/gun = null

/obj/item/projectile/energy/chrono_beam/fire()
	gun = firer.get_active_hand()
	if(istype(gun))
		return ..()
	else
		return 0

/obj/item/projectile/energy/chrono_beam/on_hit(var/atom/target)
	if(target && gun && isliving(target))
		var/obj/effect/chrono_field/F = new(target.loc, target, gun)
		gun.field_connect(F)

/obj/item/ammo_casing/energy/chrono_beam
	name = "eradication beam"
	projectile_type = /obj/item/projectile/energy/chrono_beam
	icon_state = "chronobolt"
	e_cost = 0

/obj/effect/chrono_field
	name = "eradication field"
	desc = "An aura of time-bluespace energy."
	icon = 'icons/effects/effects.dmi'
	icon_state = "chronofield"
	density = 0
	anchored = 1
	unacidable = 1
	blend_mode = BLEND_MULTIPLY
	var/mob/living/captured = null
	var/obj/item/weapon/gun/energy/chrono_gun/gun = null
	var/tickstokill = 15
	var/image/mob_underlay = null
	var/preloaded = 0
	var/RPpos = null

/obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/weapon/gun/energy/chrono_gun/G)
	if(target && isliving(target) && G)
		target.loc = src
		src.captured = target
		var/icon/mob_snapshot = getFlatIcon(target)
		var/icon/cached_icon = new()

		for(var/i=1, i<=CHRONO_FRAME_COUNT, i++)
			var/icon/removing_frame = icon('icons/obj/chronos.dmi', "erasing", SOUTH, i)
			var/icon/mob_icon = icon(mob_snapshot)
			mob_icon.Blend(removing_frame, ICON_MULTIPLY)
			cached_icon.Insert(mob_icon, "frame[i]")

		mob_underlay = new(cached_icon, "frame1")
		update_icon()

		desc = initial(desc) + "
It appears to contain [target.name]."
	SSobj.processing |= src

/obj/effect/chrono_field/Destroy()
	if(gun && gun.field_check(src))
		gun.field_disconnect(src)
	..()

/obj/effect/chrono_field/update_icon()
	var/ttk_frame = 1 - (tickstokill / initial(tickstokill))
	ttk_frame = Clamp(Ceiling(ttk_frame * CHRONO_FRAME_COUNT), 1, CHRONO_FRAME_COUNT)
	if(ttk_frame != RPpos)
		RPpos = ttk_frame
		mob_underlay.icon_state = "frame[RPpos]"
		underlays = list() //hack: BYOND refuses to update the underlay to match the icon_state otherwise
		underlays += mob_underlay

/obj/effect/chrono_field/process()
	if(captured)
		if(tickstokill > initial(tickstokill))
			for(var/atom/movable/AM in contents)
				AM.loc = loc
			qdel(src)
		else if(tickstokill <= 0)
			captured << "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy..."
			var/mob/dead/observer/ghost = captured.ghostize(1)
			if(captured.mind)
				if(ghost)
					ghost.mind = null
				if(gun)
					gun.pass_mind(captured.mind)
				if(ticker)
					ticker.minds -= captured.mind
			qdel(captured)
			qdel(src)
		else
			captured.Paralyse(4)
			if(captured.loc != src)
				captured.loc = src
			update_icon()
			if(gun)
				if(gun.field_check(src))
					tickstokill--
				else
					gun = null
					return .()
			else
				tickstokill++
	else
		qdel(src)

/obj/effect/chrono_field/bullet_act(var/obj/item/projectile/P)
	if(istype(P, /obj/item/projectile/energy/chrono_beam))
		var/obj/item/projectile/energy/chrono_beam/beam = P
		var/obj/item/weapon/gun/energy/chrono_gun/Pgun = beam.gun
		if(Pgun && istype(Pgun))
			Pgun.field_connect(src)
	else
		return 0

/obj/effect/chrono_field/assume_air()
	return 0

/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
	var/datum/gas_mixture/GM = new
	GM.oxygen = MOLES_O2STANDARD
	GM.nitrogen = MOLES_N2STANDARD
	GM.temperature = T20C
	return GM

/obj/effect/chrono_field/Move()
	return

/obj/effect/chrono_field/singularity_act()
	return

/obj/effect/chrono_field/ex_act()
	return

/obj/effect/chrono_field/blob_act()
	return

#undef CHRONO_BEAM_RANGE
#undef CHRONO_FRAME_COUNT

license: mit


code:
//cleansed 9/15/2012 17:48

/*
CONTAINS:
MATCHES
CIGARETTES
CIGARS
SMOKING PIPES
CHEAP LIGHTERS
ZIPPO

CIGARETTE PACKETS ARE IN FANCY.DM
*/

///////////
//MATCHES//
///////////
/obj/item/weapon/match
	name = "match"
	desc = "A simple match stick, used for lighting fine smokables."
	icon = 'icons/obj/cigarettes.dmi'
	icon_state = "match_unlit"
	var/lit = 0
	var/smoketime = 5
	w_class = 1.0
	origin_tech = "materials=1"
	attack_verb = null

/obj/item/weapon/match/process()
	var/turf/location = get_turf(src)
	smoketime--
	if(smoketime < 1)
		matchburnout()
		return
	if(location)
		location.hotspot_expose(700, 5)
		return

/obj/item/weapon/match/fire_act()
	matchignite()

/obj/item/weapon/match/proc/matchignite()
	if(lit == 0)
		lit = 1
		icon_state = "match_lit"
		damtype = "fire"
		force = 3
		hitsound = 'sound/items/welder.ogg'
		item_state = "cigon"
		name = "lit match"
		desc = "A match. This one is lit."
		attack_verb = list("burnt","singed")
		SSobj.processing |= src
		update_icon()
	return

/obj/item/weapon/match/proc/matchburnout()
	if(lit == 1)
		lit = -1
		damtype = "brute"
		force = initial(force)
		icon_state = "match_burnt"
		item_state = "cigoff"
		name = "burnt match"
		desc = "A match. This one has seen better days."
		attack_verb = null
		SSobj.processing.Remove(src)

/obj/item/weapon/match/dropped(mob/user as mob)
	matchburnout()
	return ..()

/obj/item/weapon/match/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
	if(!isliving(M))
		return
	M.IgniteMob()
	var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user)
	if(lit && cig)
		if(M == user)
			cig.attackby(src, user)
		else
			cig.light("[user] holds the [name] out for [M], and lights the [cig.name].")
	else
		..()

/obj/item/proc/help_light_cig(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
	if(!iscarbon(M))
		return
	if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth")
		var/obj/item/clothing/mask/cigarette/cig = M.wear_mask
		return cig

//////////////////
//FINE SMOKABLES//
//////////////////
/obj/item/clothing/mask/cigarette
	name = "cigarette"
	desc = "A roll of tobacco and nicotine."
	icon_state = "cigoff"
	throw_speed = 0.5
	item_state = "cigoff"
	w_class = 1
	body_parts_covered = null
	attack_verb = null
	var/lit = 0
	var/icon_on = "cigon"  //Note - these are in masks.dmi not in cigarette.dmi
	var/icon_off = "cigoff"
	var/type_butt = /obj/item/weapon/cigbutt
	var/lastHolder = null
	var/smoketime = 300
	var/chem_volume = 30

/obj/item/clothing/mask/cigarette/suicide_act(mob/user)
	user.visible_message("[user] is huffing the [src.name] as quickly as they can! It looks like \he's trying to give \himself cancer.")
	return (TOXLOSS|OXYLOSS)

/obj/item/clothing/mask/cigarette/New()
	..()
	flags |= NOREACT // so it doesn't react until you light it
	create_reagents(chem_volume) // making the cigarette a chemical holder with a maximum volume of 15
	reagents.add_reagent("nicotine", 15)

/obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	..()
	if(!lit && smoketime > 0)
		var/lighting_text = is_lighter(W,user)
		if(lighting_text)
			light(lighting_text)
			return

/obj/item/clothing/mask/cigarette/afterattack(obj/item/weapon/reagent_containers/glass/glass, mob/user as mob, proximity)
	if(!proximity) return
	if(istype(glass))	//you can dip cigarettes into beakers
		var/transfered = glass.reagents.trans_to(src, chem_volume)
		if(transfered)	//if reagents were transfered, show the message
			user << "You dip \the [src] into \the [glass]."
		else			//if not, either the beaker was empty, or the cigarette was full
			if(!glass.reagents.total_volume)
				user << "[glass] is empty."
			else
				user << "[src] is full."

/obj/item/clothing/mask/cigarette/proc/is_lighter(obj/O, mob/user)
	var/lighting_text = null
	if(istype(O, /obj/item/weapon/weldingtool))
		lighting_text = "[user] casually lights the [name] with [O], what a badass."
	else if(istype(O, /obj/item/weapon/lighter/zippo))
		lighting_text = "With a single flick of their wrist, [user] smoothly lights their [name] with [O]. Damn they're cool."
	else if(istype(O, /obj/item/weapon/lighter))
		lighting_text = "After some fiddling, [user] manages to light their [name] with [O]."
	else if(istype(O, /obj/item/weapon/melee/energy))
		lighting_text = "[user] swings their [O], barely missing their nose. They light their [name] in the process."
	else if(istype(O, /obj/item/device/assembly/igniter))
		lighting_text = "[user] fiddles with [O], and manages to light their [name]."
	else if(istype(O, /obj/item/device/flashlight/flare))
		lighting_text = "[user] lights their [name] with [O] like a real badass."
	else if(is_hot(O))
		lighting_text = "[user] lights their [name] with [O]."
	return lighting_text

/obj/item/clothing/mask/cigarette/proc/light(var/flavor_text = null)
	if(!src.lit)
		src.lit = 1
		name = "lit [name]"
		attack_verb = list("burnt", "singed")
		hitsound = 'sound/items/welder.ogg'
		damtype = "fire"
		force = 4
		if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire
			var/datum/effect/effect/system/reagents_explosion/e = new()
			e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0)
			e.start()
			if(ismob(loc))
				var/mob/M = loc
				M.unEquip(src, 1)
			qdel(src)
			return
		if(reagents.get_reagent_amount("fuel")) // the fuel explodes, too, but much less violently
			var/datum/effect/effect/system/reagents_explosion/e = new()
			e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0)
			e.start()
			if(ismob(loc))
				var/mob/M = loc
				M.unEquip(src, 1)
			qdel(src)
			return
		flags &= ~NOREACT // allowing reagents to react after being lit
		reagents.handle_reactions()
		icon_state = icon_on
		item_state = icon_on
		if(flavor_text)
			var/turf/T = get_turf(src)
			T.visible_message(flavor_text)
		SSobj.processing |= src

		//can't think of any other way to update the overlays :<
		if(ismob(loc))
			var/mob/M = loc
			M.update_inv_wear_mask(0)
			M.update_inv_l_hand(0)
			M.update_inv_r_hand(0)

/obj/item/clothing/mask/cigarette/proc/handle_reagents()
	if(iscarbon(loc))
		var/mob/living/carbon/C = loc
		if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob
			if(prob(15)) // so it's not an instarape in case of acid
				reagents.reaction(C, INGEST)
			reagents.trans_to(C, REAGENTS_METABOLISM)
			return
	reagents.remove_any(REAGENTS_METABOLISM)

/obj/item/clothing/mask/cigarette/process()
	var/turf/location = get_turf(src)
	var/mob/living/M = loc
	if(isliving(loc))
		M.IgniteMob()
	smoketime--
	if(smoketime < 1)
		new type_butt(location)
		SSobj.processing.Remove(src)
		if(ismob(loc))
			M << "Your [name] goes out."
			M.unEquip(src, 1)	//un-equip it so the overlays can update //Force the un-equip so the overlays update
		qdel(src)
		return
	if(location)
		location.hotspot_expose(700, 5)
	if(reagents && reagents.total_volume)	//	check if it has any reagents at all
		handle_reagents()
	return

/obj/item/clothing/mask/cigarette/attack_self(mob/user as mob)
	if(lit == 1)
		user.visible_message("[user] calmly drops and treads on \the [src], putting it out instantly.")
		var/turf/T = get_turf(src)
		new type_butt(T)
		new /obj/effect/decal/cleanable/ash(T)
		SSobj.processing.Remove(src)
		qdel(src)
	return ..()

/obj/item/clothing/mask/cigarette/attack(mob/living/carbon/M, mob/living/carbon/user)
	if(!istype(M))
		return ..()
	var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user)
	if(lit && cig)
		if(M == user)
			cig.attackby(src, user)
		else
			cig.light("[user] holds the [name] out for [M], and lights the [cig.name].")
	else
		return ..()

/obj/item/clothing/mask/cigarette/fire_act()
	light()

/obj/item/clothing/mask/cigarette/rollie
	name = "rollie"
	desc = "A roll of dried plant matter wrapped in thin paper."
	icon_state = "spliffoff"
	icon_on = "spliffon"
	icon_off = "spliffoff"
	type_butt = /obj/item/weapon/cigbutt/roach
	throw_speed = 0.5
	item_state = "spliffoff"
	smoketime = 180
	chem_volume = 50

/obj/item/clothing/mask/cigarette/rollie/New()
	..()
	src.pixel_x = rand(-5.0, 5)
	src.pixel_y = rand(-5.0, 5)

/obj/item/clothing/mask/cigarette/rollie/trippy/New()
	..()
	reagents.add_reagent("mushroomhallucinogen", 50)
	light()
	//for(var/mob/M in player_list)	M << 'sound/misc/Smoke_Weed_Everyday.ogg'

/obj/item/weapon/cigbutt/roach
	name = "roach"
	desc = "A manky old roach."
	icon_state = "roach"

/obj/item/weapon/cigbutt/roach/New()
	..()
	src.pixel_x = rand(-5.0, 5)
	src.pixel_y = rand(-5.0, 5)

////////////
// CIGARS //
////////////
/obj/item/clothing/mask/cigarette/cigar
	name = "premium cigar"
	desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!"
	icon_state = "cigaroff"
	icon_on = "cigaron"
	icon_off = "cigaroff"
	type_butt = /obj/item/weapon/cigbutt/cigarbutt
	throw_speed = 0.5
	item_state = "cigaroff"
	smoketime = 1500
	chem_volume = 20

/obj/item/clothing/mask/cigarette/cigar/cohiba
	name = "\improper Cohiba Robusto cigar"
	desc = "There's little more you could want from a cigar."
	icon_state = "cigar2off"
	icon_on = "cigar2on"
	icon_off = "cigar2off"

/obj/item/clothing/mask/cigarette/cigar/havana
	name = "premium Havanian cigar"
	desc = "A cigar fit for only the best for the best."
	icon_state = "cigar2off"
	icon_on = "cigar2on"
	icon_off = "cigar2off"
	smoketime = 7200
	chem_volume = 30

/obj/item/weapon/cigbutt
	name = "cigarette butt"
	desc = "A manky old cigarette butt."
	icon = 'icons/obj/clothing/masks.dmi'
	icon_state = "cigbutt"
	w_class = 1
	throwforce = 0

/obj/item/weapon/cigbutt/cigarbutt
	name = "cigar butt"
	desc = "A manky old cigar butt."
	icon_state = "cigarbutt"

/////////////////
//SMOKING PIPES//
/////////////////
/obj/item/clothing/mask/cigarette/pipe
	name = "smoking pipe"
	desc = "A pipe, for smoking. Probably made of meershaum or something."
	icon_state = "pipeoff"
	item_state = "pipeoff"
	icon_on = "pipeon"  //Note - these are in masks.dmi
	icon_off = "pipeoff"
	smoketime = 0
	chem_volume = 100
	var/packeditem = 0

/obj/item/clothing/mask/cigarette/pipe/process()
	var/turf/location = get_turf(src)
	smoketime--
	if(smoketime < 1)
		new /obj/effect/decal/cleanable/ash(location)
		if(ismob(loc))
			var/mob/living/M = loc
			M << "Your [name] goes out, and you empty the ash."
			lit = 0
			icon_state = icon_off
			item_state = icon_off
			M.update_inv_wear_mask(0)
			packeditem = 0
			name = "empty [initial(name)]"
		SSobj.processing.Remove(src)
		return
	if(location)
		location.hotspot_expose(700, 5)
	if(reagents && reagents.total_volume)	//	check if it has any reagents at all
		handle_reagents()
	return

/obj/item/clothing/mask/cigarette/pipe/attackby(var/obj/item/O, var/mob/user, params)
	if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown))
		var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
		if(!packeditem)
			if(G.dry == 1)
				user << "You stuff [O] into [src]."
				smoketime = 400
				packeditem = 1
				name = "[O.name]-packed [initial(name)]"
				if(O.reagents)
					O.reagents.trans_to(src, O.reagents.total_volume)
				qdel(O)
			else
				user << "It has to be dried first."
		else
			user << "It is already packed."
	else
		var/lighting_text = is_lighter(O,user)
		if(lighting_text)
			if(smoketime > 0)
				light(lighting_text)
			else
				user << "There is nothing to smoke!"
		else
			user << "You can't put that in the pipe!"
	..()

/obj/item/clothing/mask/cigarette/pipe/attack_self(mob/user as mob)
	var/turf/location = get_turf(user)
	if(lit)
		user.visible_message("[user] puts out [src].")
		lit = 0
		icon_state = icon_off
		item_state = icon_off
		SSobj.processing.Remove(src)
		return
	if(!lit && smoketime > 0)
		user << "You empty [src] onto [location]."
		new /obj/effect/decal/cleanable/ash(location)
		packeditem = 0
		smoketime = 0
		reagents.clear_reagents()
		name = "empty [initial(name)]"
	return

/obj/item/clothing/mask/cigarette/pipe/cobpipe
	name = "corn cob pipe"
	desc = "A nicotine delivery system popularized by folksy backwoodsmen and kept popular in the modern age and beyond by space hipsters. Can be loaded with objects."
	icon_state = "cobpipeoff"
	item_state = "cobpipeoff"
	icon_on = "cobpipeon"  //Note - these are in masks.dmi
	icon_off = "cobpipeoff"
	smoketime = 0

/obj/item/clothing/mask/cigarette/pipe/cobpipe/New()
	..()
	name = "empty [initial(name)]"

/////////
//ZIPPO//
/////////
/obj/item/weapon/lighter
	name = "cheap lighter"
	desc = "A cheap-as-free lighter."
	icon = 'icons/obj/items.dmi'
	icon_state = "lighter-g"
	item_state = "lighter-g"
	var/icon_on = "lighter-g-on"
	var/icon_off = "lighter-g"
	w_class = 1
	throwforce = 0
	flags = CONDUCT
	slot_flags = SLOT_BELT
	attack_verb = null
	var/lit = 0

/obj/item/weapon/lighter/grayscale
	name = "cheap lighter"
	desc ="A cheap-as-free lighter."
	icon = 'icons/obj/cigarettes.dmi'
	icon_state = "lighter-off"
	item_state = "lighter-off"
	icon_on = "lighter-on"
	icon_off = "lighter-off"

/obj/item/weapon/lighter/grayscale/New()
	var/icon/overlay = new /icon('icons/obj/cigarettes.dmi',"lighter-overlay")
	overlay.ColorTone(color2hex(randomColor(1)))
	overlays += overlay

/obj/item/weapon/lighter/zippo
	name = "\improper Zippo lighter"
	desc = "The zippo."
	icon_state = "zippo"
	item_state = "zippo"
	icon_on = "zippoon"
	icon_off = "zippo"

/obj/item/weapon/lighter/update_icon()
	icon_state = lit ? icon_on : icon_off

/obj/item/weapon/lighter/random
	New()
		var/color = pick("r","c","y","g")
		icon_on = "lighter-[color]-on"
		icon_off = "lighter-[color]"
		icon_state = icon_off

/obj/item/weapon/lighter/attack_self(mob/living/user)
	if(user.r_hand == src || user.l_hand == src)
		if(!lit)
			lit = 1
			update_icon()
			force = 5
			damtype = "fire"
			hitsound = 'sound/items/welder.ogg'
			attack_verb = list("burnt", "singed")
			if(istype(src, /obj/item/weapon/lighter/zippo) )
				user.visible_message("Without even breaking stride, [user] flips open and lights [src] in one smooth movement.")
			else
				if(prob(75))
					user.visible_message("After a few attempts, [user] manages to light [src].")
				else
					user << "You burn yourself while lighting the lighter."
					user.adjustFireLoss(5)
					user.visible_message("After a few attempts, [user] manages to light [src], they however burn their finger in the process.")

			set_light(2)
			SSobj.processing |= src
		else
			lit = 0
			update_icon()
			hitsound = "swing_hit"
			force = 0
			attack_verb = null //human_defense.dm takes care of it
			if(istype(src, /obj/item/weapon/lighter/zippo) )
				user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what they're doing. Wow.")
			else
				user.visible_message("[user] quietly shuts off [src].")

			set_light(0)
			SSobj.processing.Remove(src)
	else
		return ..()
	return

/obj/item/weapon/lighter/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
	if(!isliving(M))
		return
	M.IgniteMob()
	var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user)
	if(lit && cig)
		if(M == user)
			cig.attackby(src, user)
		else
			if(istype(src, /obj/item/weapon/lighter/zippo))
				cig.light("[user] whips the [name] out and holds it for [M]. Their arm is as steady as the unflickering flame they light \the [cig] with.")
			else
				cig.light("[user] holds the [name] out for [M], and lights the [cig.name].")
	else
		..()

/obj/item/weapon/lighter/process()
	var/turf/location = get_turf(src)
	if(location)
		location.hotspot_expose(700, 5)
	return

///////////
//ROLLING//
///////////
/obj/item/weapon/rollingpaper
	name = "rolling paper"
	desc = "A thin piece of paper used to make fine smokeables."
	icon = 'icons/obj/cigarettes.dmi'
	icon_state = "cig_paper"
	w_class = 1

/obj/item/weapon/rollingpaper/afterattack(atom/target, mob/user as mob, proximity)
	if(!proximity)
		return
	if(istype(target, /obj/item/weapon/reagent_containers/food/snacks/grown))
		var/obj/item/weapon/reagent_containers/food/snacks/grown/O = target
		if(O.dry)
			user.unEquip(target, 1)
			user.unEquip(src, 1)
			var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc)
			R.chem_volume = target.reagents.total_volume
			target.reagents.trans_to(R, R.chem_volume)
			user.put_in_active_hand(R)
			user << "You roll the [target.name] into a rolling paper."
			R.desc = "Dried [target.name] rolled up in a thin piece of paper."
			qdel(target)
			qdel(src)
		else
			user << "You need to dry this first."
	else
		..()


code:
/* Clown Items
 * Contains:
 *		Soap
 *		Bike Horns
 *		Air Horns
 */

/*
 * Soap
 */

/obj/item/weapon/soap
	name = "soap"
	desc = "A cheap bar of soap. Doesn't smell."
	gender = PLURAL
	icon = 'icons/obj/items.dmi'
	icon_state = "soap"
	w_class = 1.0
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	var/cleanspeed = 50 //slower than mop

/obj/item/weapon/soap/nanotrasen
	desc = "A Nanotrasen brand bar of soap. Smells of plasma."
	icon_state = "soapnt"

/obj/item/weapon/soap/deluxe
	desc = "A deluxe Waffle Co. brand bar of soap. Smells of high-class luxury."
	icon_state = "soapdeluxe"
	cleanspeed = 40 //same speed as mop because deluxe -- captain gets one of these

/obj/item/weapon/soap/syndie
	desc = "An untrustworthy bar of soap made of strong chemical agents that dissolve blood faster."
	icon_state = "soapsyndie"
	cleanspeed = 10 //much faster than mop so it is useful for traitors who want to clean crime scenes

/obj/item/weapon/soap/Crossed(AM as mob|obj)
	if (istype(AM, /mob/living/carbon))
		var/mob/living/carbon/M = AM
		M.slip(4, 2, src)

/obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity)
	if(!proximity || !check_allowed_items(target))
		return
	//I couldn't feasibly  fix the overlay bugs caused by cleaning items we are wearing.
	//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
	if(user.client && (target in user.client.screen))
		user << "You need to take that [target.name] off before cleaning it."
	else if(istype(target,/obj/effect/decal/cleanable))
		user.visible_message("[user] begins to scrub \the [target.name] out with [src].")
		if(do_after(user, src.cleanspeed))
			user << "You scrub \the [target.name] out."
			qdel(target)
	else if(ishuman(target) && user.zone_sel && user.zone_sel.selecting == "mouth")
		user.visible_message("\the [user] washes \the [target]'s mouth out with [src.name]!") //washes mouth out with soap sounds better than 'the soap' here
		return
	else
		user.visible_message("[user] begins to clean \the [target.name] with [src].")
		if(do_after(user, src.cleanspeed))
			user << "You clean \the [target.name]."
			var/obj/effect/decal/cleanable/C = locate() in target
			qdel(C)
			target.clean_blood()
	return

/*
 * Bike Horns
 */

/obj/item/weapon/bikehorn
	name = "bike horn"
	desc = "A horn off of a bicycle."
	icon = 'icons/obj/items.dmi'
	icon_state = "bike_horn"
	item_state = "bike_horn"
	throwforce = 0
	hitsound = null //To prevent tap.ogg playing, as the item lacks of force
	w_class = 1.0
	throw_speed = 3
	throw_range = 7
	attack_verb = list("HONKED")
	var/spam_flag = 0
	var/honksound = 'sound/items/bikehorn.ogg'
	var/cooldowntime = 20

/obj/item/weapon/bikehorn/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
	if(!spam_flag)
		playsound(loc, honksound, 50, 1, -1) //plays instead of tap.ogg!
	return ..()

/obj/item/weapon/bikehorn/attack_self(mob/user as mob)
	if(!spam_flag)
		spam_flag = 1
		playsound(src.loc, honksound, 50, 1)
		src.add_fingerprint(user)
		spawn(cooldowntime)
			spam_flag = 0
	return

/obj/item/weapon/bikehorn/airhorn
	name = "air horn"
	desc = "Damn son, where'd you find this?"
	icon_state = "air_horn"
	honksound = 'sound/items/AirHorn2.ogg'
	cooldowntime = 50


code:
/obj/item/weapon/lipstick
	gender = PLURAL
	name = "red lipstick"
	desc = "A generic brand of lipstick."
	icon = 'icons/obj/items.dmi'
	icon_state = "lipstick"
	w_class = 1
	var/colour = "red"
	var/open = 0

/obj/item/weapon/lipstick/purple
	name = "purple lipstick"
	colour = "purple"

/obj/item/weapon/lipstick/jade
	name = "jade lipstick"
	colour = "jade"

/obj/item/weapon/lipstick/black
	name = "black lipstick"
	colour = "black"

/obj/item/weapon/lipstick/random
	name = "lipstick"

/obj/item/weapon/lipstick/random/New()
	colour = pick("red","purple","jade","black")
	name = "[colour] lipstick"

/obj/item/weapon/lipstick/attack_self(mob/user)
	user << "You twist \the [src] [open ? "closed" : "open"]."
	open = !open
	if(open)
		icon_state = "[initial(icon_state)]_[colour]"
	else
		icon_state = initial(icon_state)

/obj/item/weapon/lipstick/attack(mob/M, mob/user)
	if(!open)	return

	if(!istype(M, /mob))	return

	if(ishuman(M))
		var/mob/living/carbon/human/H = M
		if(H.lip_style)	//if they already have lipstick on
			user << "You need to wipe off the old lipstick first!"
			return
		if(H == user)
			user.visible_message("[user] does their lips with \the [src].", \
								 "You take a moment to apply \the [src]. Perfect!")
			H.lip_style = colour
			H.update_body()
		else
			user.visible_message("[user] begins to do [H]'s lips with \the [src].", \
								 "You begin to apply \the [src].")
			if(do_after(user, 20) && do_after(H, 20, 5, 0))	//user needs to keep their active hand, H does not.
				user.visible_message("[user] does [H]'s lips with \the [src].", \
									 "You apply \the [src].")
				H.lip_style = colour
				H.update_body()
	else
		user << "Where are the lips on that?"

//you can wipe off lipstick with paper!
/obj/item/weapon/paper/attack(mob/M, mob/user)
	if(user.zone_sel.selecting == "mouth")
		if(!ismob(M))
			return

		if(ishuman(M))
			var/mob/living/carbon/human/H = M
			if(H == user)
				user << "You wipe off the lipstick with [src]."
				H.lip_style = null
				H.update_body()
			else
				user.visible_message("[user] begins to wipe [H]'s lipstick off with \the [src].", \
								 	 "You begin to wipe off [H]'s lipstick.")
				if(do_after(user, 10) && do_after(H, 10, 5, 0))	//user needs to keep their active hand, H does not.
					user.visible_message("[user] wipes [H]'s lipstick off with \the [src].", \
										 "You wipe off [H]'s lipstick.")
					H.lip_style = null
					H.update_body()
	else
		..()

/obj/item/weapon/razor
	name = "electric razor"
	desc = "The latest and greatest power razor born from the science of shaving."
	icon = 'icons/obj/items.dmi'
	icon_state = "razor"
	flags = CONDUCT
	w_class = 1

/obj/item/weapon/razor/proc/shave(mob/living/carbon/human/H, location = "mouth")
	if(location == "mouth")
		H.facial_hair_style = "Shaved"
	else
		H.hair_style = "Skinhead"

	H.update_hair()
	playsound(loc, 'sound/items/Welder2.ogg', 20, 1)

/obj/item/weapon/razor/attack(mob/M, mob/user)
	if(ishuman(M))
		var/mob/living/carbon/human/H = M

		var/location = user.zone_sel.selecting
		if(location == "mouth")
			if(!get_location_accessible(H, location))
				user << "The mask is in the way."
				return
			if(H.facial_hair_style == "Shaved")
				user << "Already clean-shaven."
				return

			if(H == user) //shaving yourself
				user.visible_message("[user] starts to shave their facial hair with [src].", \
									 "You take a moment to shave your facial hair with [src].")
				if(do_after(user, 50))
					user.visible_message("[user] shaves his facial hair clean with [src].", \
										 "You finish shaving with [src]. Fast and clean!")
					shave(H, location)
			else
				var/turf/H_loc = H.loc
				user.visible_message("[user] tries to shave [H]'s facial hair with [src].", \
									 "You start shaving [H]'s facial hair.")
				if(do_after(user, 50))
					if(H_loc == H.loc)
						user.visible_message("[user] shaves off [H]'s facial hair with [src].", \
											 "You shave [H]'s facial hair clean off.")
						shave(H, location)

		else if(location == "head")
			if(!get_location_accessible(H, location))
				user << "The headgear is in the way."
				return
			if(H.hair_style == "Bald" || H.hair_style == "Balding Hair" || H.hair_style == "Skinhead")
				user << "There is not enough hair left to shave!"
				return

			if(H == user) //shaving yourself
				user.visible_message("[user] starts to shave their head with [src].", \
									 "You start to shave your head with [src].")
				if(do_after(user, 50))
					user.visible_message("[user] shaves his head with [src].", \
										 "You finish shaving with [src].")
					shave(H, location)
			else
				var/turf/H_loc = H.loc
				user.visible_message("[user] tries to shave [H]'s head with [src]!", \
									 "You start shaving [H]'s head.")
				if(do_after(user, 50))
					if(H_loc == H.loc)
						user.visible_message("[user] shaves [H]'s head bald with [src]!", \
											 "You shave [H]'s head bald.")
						shave(H, location)
		else
			..()
	else
		..()


code:
//backpack item

/obj/item/weapon/defibrillator
	name = "defibrillator"
	desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
	icon = 'icons/obj/weapons.dmi'
	icon_state = "defibunit"
	item_state = "defibunit"
	slot_flags = SLOT_BACK
	force = 5
	throwforce = 6
	w_class = 4
	origin_tech = "biotech=4"
	action_button_name = "Toggle Paddles"

	var/on = 0 //if the paddles are equipped (1) or on the defib (0)
//	var/safety = 1 //if you can zap people with the defibs on harm mode
	var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
	var/obj/item/weapon/twohanded/shockpaddles/paddles
	var/obj/item/weapon/stock_parts/cell/high/bcell = null
	var/combat = 0 //can we revive through space suits?

/obj/item/weapon/defibrillator/New() //starts without a cell for rnd
	..()
	paddles = make_paddles()
	update_icon()
	return

/obj/item/weapon/defibrillator/loaded/New() //starts with hicap
	..()
	paddles = make_paddles()
	bcell = new(src)
	update_icon()
	return

/obj/item/weapon/defibrillator/update_icon()
	update_power()
	update_overlays()
	update_charge()

/obj/item/weapon/defibrillator/proc/update_power()
	if(bcell)
		if(bcell.charge < paddles.revivecost)
			powered = 0
		else
			powered = 1
	else
		powered = 0

/obj/item/weapon/defibrillator/proc/update_overlays()
	overlays.Cut()
	if(!on)
		overlays += "[initial(icon_state)]-paddles"
	if(powered)
		overlays += "[initial(icon_state)]-powered"
	if(!bcell)
		overlays += "[initial(icon_state)]-nocell"
//	if(!safety)
//		overlays += "[initial(icon_state)]-emagged"

/obj/item/weapon/defibrillator/proc/update_charge()
	if(powered) //so it doesn't show charge if it's unpowered
		if(bcell)
			var/ratio = bcell.charge / bcell.maxcharge
			ratio = Ceiling(ratio*4) * 25
			overlays += "[initial(icon_state)]-charge[ratio]"

/obj/item/weapon/defibrillator/CheckParts()
	bcell = locate(/obj/item/weapon/stock_parts/cell) in contents
	update_icon()

/obj/item/weapon/defibrillator/ui_action_click()
	if(usr.get_item_by_slot(slot_back) == src)
		toggle_paddles()
	else
		usr << "Put the defibrillator on your back first!"
	return

/obj/item/weapon/defibrillator/attack_hand(mob/user as mob)
	if(src.loc == user)
		ui_action_click()
		return
	..()

/obj/item/weapon/defibrillator/MouseDrop(obj/over_object)
	if(ishuman(src.loc))
		var/mob/living/carbon/human/H = src.loc
		switch(over_object.name)
			if("r_hand")
				if(H.r_hand)
					return
				if(!H.unEquip(src))
					return
				H.put_in_r_hand(src)
			if("l_hand")
				if(H.l_hand)
					return
				if(!H.unEquip(src))
					return
				H.put_in_l_hand(src)
	return

/obj/item/weapon/defibrillator/attackby(obj/item/weapon/W, mob/user, params)
	if(W == paddles)
		paddles.unwield()
		toggle_paddles()
	if(istype(W, /obj/item/weapon/stock_parts/cell))
		var/obj/item/weapon/stock_parts/cell/C = W
		if(bcell)
			user << "[src] already has a cell."
		else
			if(C.maxcharge < paddles.revivecost)
				user << "[src] requires a higher capacity cell."
				return
			user.drop_item()
			W.loc = src
			bcell = W
			user << "You install a cell in [src]."

	if(istype(W, /obj/item/weapon/screwdriver))
		if(bcell)
			bcell.updateicon()
			bcell.loc = get_turf(src.loc)
			bcell = null
			user << "You remove the cell from [src]."

	update_icon()
	return
/*
/obj/item/weapon/defibrillator/emag_act(mob/user as mob)
	if(safety)
		safety = 0
		user << "You silently disable [src]'s safety protocols with the cryptographic sequencer."
	else
		safety = 1
		user << "You silently enable [src]'s safety protocols with the cryptographic sequencer."
*/
/obj/item/weapon/defibrillator/emp_act(severity)
	if(bcell)
		deductcharge(1000 / severity)
		if(bcell.reliability != 100 && prob(50/severity))
			bcell.reliability -= 10 / severity
/*	if(safety)
		safety = 0
		src.visible_message("[src] beeps: Safety protocols disabled!")
		playsound(get_turf(src), 'sound/machines/defib_saftyOff.ogg', 50, 0)
	else
		safety = 1
		src.visible_message("[src] beeps: Safety protocols enabled!")
		playsound(get_turf(src), 'sound/machines/defib_saftyOn.ogg', 50, 0) */
	update_icon()
	..()

/obj/item/weapon/defibrillator/proc/toggle_paddles()
	set name = "Toggle Paddles"
	set category = "Object"
	on = !on

	var/mob/living/carbon/human/user = usr
	if(on)
		//Detach the paddles into the user's hands
		if(!usr.put_in_hands(paddles))
			on = 0
			user << "You need a free hand to hold the paddles!"
			update_icon()
			return
		paddles.loc = user
	else
		//Remove from their hands and back onto the defib unit
		paddles.unwield()
		remove_paddles(user)

	update_icon()
	return

/obj/item/weapon/defibrillator/proc/make_paddles()
	return new /obj/item/weapon/twohanded/shockpaddles(src)

/obj/item/weapon/defibrillator/equipped(mob/user, slot)
	if(slot != slot_back)
		remove_paddles(user)
		update_icon()

/obj/item/weapon/defibrillator/proc/remove_paddles(mob/user)
	var/mob/living/carbon/human/M = user
	if(paddles in get_both_hands(M))
		M.unEquip(paddles,1)
	update_icon()
	return

/obj/item/weapon/defibrillator/Destroy()
	if(on)
		var/M = get(paddles, /mob)
		remove_paddles(M)
	..()
	update_icon()
	return

/obj/item/weapon/defibrillator/proc/deductcharge(var/chrgdeductamt)
	if(bcell)
		if(bcell.charge < (paddles.revivecost+chrgdeductamt))
			powered = 0
			update_icon()
		if(bcell.use(chrgdeductamt))
			update_icon()
			return 1
		else
			update_icon()
			return 0

/obj/item/weapon/defibrillator/proc/cooldowncheck(var/mob/user)
	spawn(50)
		if(bcell)
			if(bcell.charge >= paddles.revivecost)
				user.visible_message("[src] beeps: Unit ready.")
				playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0)
			else
				user.visible_message("[src] beeps: Charge depleted.")
				playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
		paddles.cooldown = 0
		paddles.update_icon()
		update_icon()

/obj/item/weapon/defibrillator/compact
	name = "compact defibrillator"
	desc = "A belt-equipped defibrillator that can be rapidly deployed."
	icon_state = "defibcompact"
	item_state = "defibcompact"
	w_class = 3
	slot_flags = SLOT_BELT
	origin_tech = "biotech=4"

/obj/item/weapon/defibrillator/compact/ui_action_click()
	if(usr.get_item_by_slot(slot_belt) == src)
		toggle_paddles()
	else
		usr << "Strap the defibrillator's belt on first!"
	return

/obj/item/weapon/defibrillator/compact/loaded/New()
	..()
	paddles = make_paddles()
	bcell = new(src)
	update_icon()
	return

/obj/item/weapon/defibrillator/compact/combat
	name = "combat defibrillator"
	desc = "A belt-equipped blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits."
	combat = 1
//	safety = 0

/obj/item/weapon/defibrillator/compact/combat/loaded/New()
	..()
	paddles = make_paddles()
	bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
	update_icon()
	return

/obj/item/weapon/defibrillator/compact/combat/attackby(obj/item/weapon/W, mob/user, params)
	if(W == paddles)
		paddles.unwield()
		toggle_paddles()
		update_icon()
		return

//paddles

/obj/item/weapon/twohanded/shockpaddles
	name = "defibrillator paddles"
	desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks."
	icon = 'icons/obj/weapons.dmi'
	icon_state = "defibpaddles"
	item_state = "defibpaddles"
	force = 0
	throwforce = 6
	w_class = 4
	flags = NODROP

	var/revivecost = 1000
	var/cooldown = 0
	var/busy = 0
	var/obj/item/weapon/defibrillator/defib

/obj/item/weapon/twohanded/shockpaddles/New(mainunit)
	..()
	if(check_defib_exists(mainunit, src))
		defib = mainunit
		loc = defib
		busy = 0
		update_icon()
	return

/obj/item/weapon/twohanded/shockpaddles/update_icon()
	icon_state = "defibpaddles[wielded]"
	item_state = "defibpaddles[wielded]"
	if(cooldown)
		icon_state = "defibpaddles[wielded]_cooldown"

/obj/item/weapon/twohanded/shockpaddles/suicide_act(mob/user)
	user.visible_message("[user] is putting the live paddles on \his chest! It looks like \he's trying to commit suicide.")
	defib.deductcharge(revivecost)
	playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
	return (OXYLOSS)

/obj/item/weapon/twohanded/shockpaddles/dropped(mob/user as mob)
	if(user)
		var/obj/item/weapon/twohanded/O = user.get_inactive_hand()
		if(istype(O))
			O.unwield()
		user << "The paddles snap back into the main unit."
		defib.on = 0
		loc = defib
		defib.update_icon()
	return	unwield()

/obj/item/weapon/twohanded/shockpaddles/proc/check_defib_exists(mainunit, var/mob/living/carbon/human/M, var/obj/O)
	if (!mainunit || !istype(mainunit, /obj/item/weapon/defibrillator))	//To avoid weird issues from admin spawns
		M.unEquip(O)
		qdel(O)
		return 0
	else
		return 1

/obj/item/weapon/twohanded/shockpaddles/attack(mob/M, mob/user)
	var/halfwaycritdeath = (config.health_threshold_crit + config.health_threshold_dead) / 2
	var/mob/living/carbon/human/H = M

	if(busy)
		return
	if(!defib.powered)
		user.visible_message("[defib] beeps: Unit is unpowered.")
		playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
		return
	if(!wielded)
		user << "You need to wield the paddles in both hands before you can use them on someone!"
		return
	if(cooldown)
		user << "[defib] is recharging."
		return
	if(!ishuman(M))
		user << "The instructions on [defib] don't mention how to revive that..."
		return
	else
		if(user.a_intent == "disarm")
			busy = 1
			H.visible_message("[user] has touched [H.name] with [src]!", \
					"[user] has touched [H.name] with [src]!")
			H.adjustStaminaLoss(50)
			H.Weaken(5)
			H.updatehealth() //forces health update before next life tick
			playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
			H.emote("gasp")
			add_logs(user, M, "stunned", object="defibrillator")
			defib.deductcharge(revivecost)
			cooldown = 1
			busy = 0
			update_icon()
			defib.cooldowncheck(user)
			return
		if(user.zone_sel && user.zone_sel.selecting == "chest")
			if(user.a_intent == "harm")
				user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You overcharge the paddles and begin to place them onto [M]'s chest...")
				busy = 1
				update_icon()
				if(do_after(user, 30, target = M))
					user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest and begin to charge them.")
					var/turf/T = get_turf(defib)
					playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
					T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...")
					if(do_after(user, 30, target = M)) //Takes longer due to overcharging
						if(M.stat == DEAD)
							user << "[M] is dead."
							playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
							busy = 0
							update_icon()
							return
						user.visible_message("[user] shocks [M] with \the [src]!", "You shock [M] with \the [src]!")
						playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
						playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
						var/mob/living/carbon/human/HU = M
						M.emote("scream")
						if(!HU.heart_attack)
							HU.heart_attack = 1
							if(!HU.stat)
								HU.visible_message("[M] thrashes wildly, clutching at their chest!", "You feel a horrible agony in your chest!")
						HU.apply_damage(50, BURN, "chest")
						add_logs(user, M, "overloaded the heart of", object="defibrillator")
						M.Weaken(5)
						M.Jitter(100)
						defib.deductcharge(revivecost)
						cooldown = 1
						busy = 0
						update_icon()
						defib.cooldowncheck(user)
						return
				busy = 0
				update_icon()
				return
		if(user.zone_sel && user.zone_sel.selecting == "chest")
			var/mob/dead/observer/ghost = H.get_ghost()
			if(ghost)
				ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)"
				ghost << 'sound/effects/genetics.ogg'
			user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest...")
			busy = 1
			update_icon()
			if(do_after(user, 30, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
				user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
				playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
				var/tplus = world.time - H.timeofdeath
				var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds)
				var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting
				var/total_burn	= 0
				var/total_brute	= 0
				if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
					for(var/obj/item/carried_item in H.contents)
						if(istype(carried_item, /obj/item/clothing/suit/space))
							if(!defib.combat)
								user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.")
								playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
								busy = 0
								update_icon()
								return
					if(H.heart_attack)
						H.heart_attack = 0
						user.visible_message("[defib] pings: Patient's heart is now beating again.")
						playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
					if(H.stat == 2)
						M.visible_message("[M]'s body convulses a bit.")
						playsound(get_turf(src), "bodyfall", 50, 1)
						playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
						for(var/obj/item/organ/limb/O in H.organs)
							total_brute	+= O.brute_dam
							total_burn	+= O.burn_dam
						ghost = H.get_ghost()
						if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations))
							//If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit
							if (H.health > halfwaycritdeath)
								H.adjustOxyLoss(H.health - halfwaycritdeath)
							else
								var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
								var/mobhealth = H.health
								H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage))
								H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage))
								H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage))
								H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage))
							user.visible_message("[defib] pings: Resuscitation successful.")
							playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
							H.stat = 1
							dead_mob_list -= H
							living_mob_list |= list(H)
							H.emote("gasp")
							if(tplus > tloss)
								H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
							defib.deductcharge(revivecost)
							add_logs(user, M, "revived", object="defibrillator")
						else
							if (H.suiciding || (NOCLONE in H.mutations))
								user.visible_message("[defib] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.")
							else if (tplus > tlimit)
								user.visible_message("[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation. Further attempts futile.")
							else if(total_burn >= 180 || total_brute >= 180)
								user.visible_message("[defib] buzzes: Resuscitation failed - Severe tissue damage detected.")
							else
								user.visible_message("[defib] buzzes: Resuscitation failed - No soul in patient body. Further attempts may be successful.")
							playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
							defib.deductcharge(revivecost)
						update_icon()
						cooldown = 1
						defib.cooldowncheck(user)
					else
						user.visible_message("[defib] buzzes: Patient is not in a valid state. Operation aborted.")
						playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
			busy = 0
			update_icon()
		else
			user << "You need to target your patient's chest with [src]!"
			return


code:
/obj/item/weapon/dice
	name = "d6"
	desc = "A die with six sides. Basic and servicable."
	icon = 'icons/obj/dice.dmi'
	icon_state = "d6"
	w_class = 1
	var/sides = 6
	var/result = null

/obj/item/weapon/dice/New()
	result = rand(1, sides)
	update_icon()

/obj/item/weapon/dice/d2
	name = "d2"
	desc = "A die with two sides. Coins are undignified!"
	icon_state = "d2"
	sides = 2

/obj/item/weapon/dice/d4
	name = "d4"
	desc = "A die with four sides. The nerd's caltrop."
	icon_state = "d4"
	sides = 4

/obj/item/weapon/dice/d8
	name = "d8"
	desc = "A die with eight sides. It feels... lucky."
	icon_state = "d8"
	sides = 8

/obj/item/weapon/dice/d10
	name = "d10"
	desc = "A die with ten sides. Useful for percentages."
	icon_state = "d10"
	sides = 10

/obj/item/weapon/dice/d00
	name = "d00"
	desc = "A die with ten sides. Works better for d100 rolls than a golfball."
	icon_state = "d00"
	sides = 10

/obj/item/weapon/dice/d12
	name = "d12"
	desc = "A die with twelve sides. There's an air of neglect about it."
	icon_state = "d12"
	sides = 12

/obj/item/weapon/dice/d20
	name = "d20"
	desc = "A die with twenty sides. The prefered die to throw at the GM."
	icon_state = "d20"
	sides = 20

/obj/item/weapon/dice/attack_self(mob/user as mob)
	diceroll(user)

/obj/item/weapon/dice/throw_at(atom/target, range, speed, mob/user as mob)
	if(!..())
		return
	diceroll(user)

/obj/item/weapon/dice/proc/diceroll(mob/user as mob)
	result = rand(1, sides)
	var/comment = ""
	if(sides == 20 && result == 20)
		comment = "Nat 20!"
	else if(sides == 20 && result == 1)
		comment = "Ouch, bad luck."
	update_icon()
	if(initial(icon_state) == "d00")
		result = (result - 1)*10
	if(user != null) //Dice was rolled in someone's hand
		user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
							 "You throw [src]. It lands on [result]. [comment]", \
							 "You hear [src] landing on [result]. [comment]")
	else if(src.throwing == 0) //Dice was thrown and is coming to rest
		visible_message("[src] rolls to a stop, landing on [result]. [comment]")

/obj/item/weapon/dice/d4/Crossed(var/mob/living/carbon/human/H)
	if(istype(H) && !H.shoes)
		if(HARDFEET in H.dna.species.specflags)
			return 0
		H << "You step on the D4!"
		H.apply_damage(4,BRUTE,(pick("l_leg", "r_leg")))
		H.Weaken(3)

/obj/item/weapon/dice/update_icon()
	overlays.Cut()
	overlays += "[src.icon_state][src.result]"


code:
/obj/item/weapon/dnainjector
	name = "\improper DNA injector"
	desc = "This injects the person with DNA."
	icon = 'icons/obj/items.dmi'
	icon_state = "dnainjector"
	throw_speed = 3
	throw_range = 5
	w_class = 1.0

	var/damage_coeff  = 1
	var/list/fields
	var/list/add_mutations = list()
	var/list/remove_mutations = list()

/obj/item/weapon/dnainjector/attack_paw(mob/user)
	return attack_hand(user)

/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
	if(check_dna_integrity(M) && !(NOCLONE in M.mutations))
		if(M.stat == DEAD)	//prevents dead people from having their DNA changed
			user << "You can't modify [M]'s DNA while \he's dead."
			return
		M.radiation += rand(20/(damage_coeff  ** 2),50/(damage_coeff  ** 2))
		var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
		for(var/datum/mutation/human/HM in remove_mutations)
			HM.force_lose(M)
		for(var/datum/mutation/human/HM in add_mutations)
			if(HM.name == RACEMUT)
				message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)")
				log_msg += " (MONKEY)"
			HM.force_give(M)
		if(fields)
			if(fields["name"] && fields["UE"] && fields["blood_type"])
				M.real_name = fields["name"]
				M.dna.unique_enzymes = fields["UE"]
				M.name = M.real_name
				M.dna.blood_type = fields["blood_type"]
			if(fields["UI"])	//UI+UE
				M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
				updateappearance(M)
		log_attack(log_msg)
	else
		user << "It appears that [M] does not have compatible DNA."
		return

/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
	if(!user.IsAdvancedToolUser())
		user << "You don't have the dexterity to do this!"
		return
	add_logs(user, target, "attempted to inject", object="[name]")

	if(target != user)
		target.visible_message("[user] is trying to inject [target] with [src]!", "[user] is trying to inject [target] with [src]!")
		if(!do_mob(user, target))	return
		target.visible_message("[user] injects [target] with the syringe with [src]!", \
						"[user] injects [target] with the syringe with [src]!")

	else
		user << "You inject yourself with [src]."

	add_logs(user, target, "injected", object="[name]")

	inject(target, user)	//Now we actually do the heavy lifting.
	qdel(src)

/obj/item/weapon/dnainjector/antihulk
	name = "\improper DNA injector (Anti-Hulk)"
	desc = "Cures green skin."
	New()
		..()
		remove_mutations.Add(mutations_list[HULK])

/obj/item/weapon/dnainjector/hulkmut
	name = "\improper DNA injector (Hulk)"
	desc = "This will make you big and strong, but give you a bad skin condition."
	New()
		..()
		add_mutations.Add(mutations_list[HULK])
/obj/item/weapon/dnainjector/xraymut
	name = "\improper DNA injector (Xray)"
	desc = "Finally you can see what the Captain does."
	New()
		..()
		add_mutations.Add(mutations_list[XRAY])

/obj/item/weapon/dnainjector/antixray
	name = "\improper DNA injector (Anti-Xray)"
	desc = "It will make you see harder."
	New()
		..()
		remove_mutations.Add(mutations_list[XRAY])

/////////////////////////////////////
/obj/item/weapon/dnainjector/antiglasses
	name = "\improper DNA injector (Anti-Glasses)"
	desc = "Toss away those glasses!"
	New()
		..()
		remove_mutations.Add(mutations_list[BADSIGHT])

/obj/item/weapon/dnainjector/glassesmut
	name = "\improper DNA injector (Glasses)"
	desc = "Will make you need dorkish glasses."
	New()
		..()
		add_mutations.Add(mutations_list[BADSIGHT])

/obj/item/weapon/dnainjector/epimut
	name = "\improper DNA injector (Epi.)"
	desc = "Shake shake shake the room!"
	New()
		..()
		add_mutations.Add(mutations_list[EPILEPSY])

/obj/item/weapon/dnainjector/antiepi
	name = "\improper DNA injector (Anti-Epi.)"
	desc = "Will fix you up from shaking the room."
	New()
		..()
		remove_mutations.Add(mutations_list[EPILEPSY])
////////////////////////////////////
/obj/item/weapon/dnainjector/anticough
	name = "\improper DNA injector (Anti-Cough)"
	desc = "Will stop that aweful noise."
	New()
		..()
		remove_mutations.Add(mutations_list[COUGH])

/obj/item/weapon/dnainjector/coughmut
	name = "\improper DNA injector (Cough)"
	desc = "Will bring forth a sound of horror from your throat."
	New()
		..()
		add_mutations.Add(mutations_list[COUGH])

/obj/item/weapon/dnainjector/clumsymut
	name = "\improper DNA injector (Clumsy)"
	desc = "Makes clown minions."
	New()
		..()
		add_mutations.Add(mutations_list[CLOWNMUT])

/obj/item/weapon/dnainjector/anticlumsy
	name = "\improper DNA injector (Anti-Clumy)"
	desc = "Apply this for Security Clown."
	New()
		..()
		remove_mutations.Add(mutations_list[CLOWNMUT])

/obj/item/weapon/dnainjector/antitour
	name = "\improper DNA injector (Anti-Tour.)"
	desc = "Will cure tourrets."
	New()
		..()
		remove_mutations.Add(mutations_list[TOURETTES])

/obj/item/weapon/dnainjector/tourmut
	name = "\improper DNA injector (Tour.)"
	desc = "Gives you a nasty case off tourrets."
	New()
		..()
		add_mutations.Add(mutations_list[TOURETTES])

/obj/item/weapon/dnainjector/stuttmut
	name = "\improper DNA injector (Stutt.)"
	desc = "Makes you s-s-stuttterrr"
	New()
		..()
		add_mutations.Add(mutations_list[NERVOUS])

/obj/item/weapon/dnainjector/antistutt
	name = "\improper DNA injector (Anti-Stutt.)"
	desc = "Fixes that speaking impairment."
	New()
		..()
		remove_mutations.Add(mutations_list[NERVOUS])

/obj/item/weapon/dnainjector/antifire
	name = "\improper DNA injector (Anti-Fire)"
	desc = "Cures fire."
	New()
		..()
		remove_mutations.Add(mutations_list[COLDRES])

/obj/item/weapon/dnainjector/firemut
	name = "\improper DNA injector (Fire)"
	desc = "Gives you fire."
	New()
		..()
		add_mutations.Add(mutations_list[COLDRES])

/obj/item/weapon/dnainjector/blindmut
	name = "\improper DNA injector (Blind)"
	desc = "Makes you not see anything."
	New()
		..()
		add_mutations.Add(mutations_list[BLINDMUT])

/obj/item/weapon/dnainjector/antiblind
	name = "\improper DNA injector (Anti-Blind)"
	desc = "ITS A MIRACLE!!!"
	New()
		..()
		remove_mutations.Add(mutations_list[BLINDMUT])

/obj/item/weapon/dnainjector/antitele
	name = "\improper DNA injector (Anti-Tele.)"
	desc = "Will make you not able to control your mind."
	New()
		..()
		remove_mutations.Add(mutations_list[TK])

/obj/item/weapon/dnainjector/telemut
	name = "\improper DNA injector (Tele.)"
	desc = "Super brain man!"
	New()
		..()
		add_mutations.Add(mutations_list[TK])

/obj/item/weapon/dnainjector/telemut/darkbundle
	name = "\improper DNA injector"
	desc = "Good. Let the hate flow through you."

/obj/item/weapon/dnainjector/deafmut
	name = "\improper DNA injector (Deaf)"
	desc = "Sorry, what did you say?"
	New()
		..()
		add_mutations.Add(mutations_list[DEAFMUT])

/obj/item/weapon/dnainjector/antideaf
	name = "\improper DNA injector (Anti-Deaf)"
	desc = "Will make you hear once more."
	New()
		..()
		remove_mutations.Add(mutations_list[DEAFMUT])

/obj/item/weapon/dnainjector/h2m
	name = "\improper DNA injector (Human > Monkey)"
	desc = "Will make you a flea bag."
	New()
		..()
		add_mutations.Add(mutations_list[RACEMUT])

/obj/item/weapon/dnainjector/m2h
	name = "\improper DNA injector (Monkey > Human)"
	desc = "Will make you...less hairy."
	New()
		..()
		remove_mutations.Add(mutations_list[RACEMUT])

/obj/item/weapon/dnainjector/antistealth
	name = "\improper DNA injector (Anti-Cloak Of Darkness)"
	New()
		..()
		remove_mutations.Add(mutations_list[STEALTH])

/obj/item/weapon/dnainjector/stealthmut
	name = "\improper DNA injector (Cloak of Darkness)"
	desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect."
	New()
		..()
		add_mutations.Add(mutations_list[STEALTH])

/obj/item/weapon/dnainjector/antichameleon
	name = "\improper DNA injector (Anti-Chameleon)"
	New()
		..()
		remove_mutations.Add(mutations_list[CHAMELEON])

/obj/item/weapon/dnainjector/chameleonmut
	name = "\improper DNA injector (Chameleon)"
	New()
		..()
		add_mutations.Add(mutations_list[CHAMELEON])

/obj/item/weapon/dnainjector/antiwacky
	name = "\improper DNA injector (Anti-Wacky)"
	New()
		..()
		remove_mutations.Add(mutations_list[WACKY])

/obj/item/weapon/dnainjector/wackymut
	name = "\improper DNA injector (Wacky)"
	New()
		..()
		add_mutations.Add(mutations_list[WACKY])

/obj/item/weapon/dnainjector/antimute
	name = "\improper DNA injector (Anti-Mute)"
	New()
		..()
		remove_mutations.Add(mutations_list[MUT_MUTE])

/obj/item/weapon/dnainjector/mutemut
	name = "\improper DNA injector (Mute)"
	New()
		..()
		add_mutations.Add(mutations_list[MUT_MUTE])

/obj/item/weapon/dnainjector/antismile
	name = "\improper DNA injector (Anti-Smile)"
	New()
		..()
		remove_mutations.Add(mutations_list[SMILE])

/obj/item/weapon/dnainjector/smilemut
	name = "\improper DNA injector (Smile)"
	New()
		..()
		add_mutations.Add(mutations_list[SMILE])

/obj/item/weapon/dnainjector/unintelligablemut
	name = "\improper DNA injector (Unintelligable)"
	New()
		..()
		add_mutations.Add(mutations_list[UNINTELLIGABLE])

/obj/item/weapon/dnainjector/antiunintelligable
	name = "\improper DNA injector (Anti-Unintelligable)"
	New()
		..()
		remove_mutations.Add(mutations_list[UNINTELLIGABLE])

/obj/item/weapon/dnainjector/swedishmut
	name = "\improper DNA injector (Swedish)"
	New()
		..()
		add_mutations.Add(mutations_list[SWEDISH])

/obj/item/weapon/dnainjector/antiswedish
	name = "\improper DNA injector (Anti-Swedish)"
	New()
		..()
		remove_mutations.Add(mutations_list[SWEDISH])

/obj/item/weapon/dnainjector/chavmut
	name = "\improper DNA injector (Chav)"
	New()
		..()
		add_mutations.Add(mutations_list[CHAV])

/obj/item/weapon/dnainjector/antichav
	name = "\improper DNA injector (Anti-Chav)"
	New()
		..()
		remove_mutations.Add(mutations_list[CHAV])

/obj/item/weapon/dnainjector/elvismut
	name = "\improper DNA injector (Elvis)"
	New()
		..()
		add_mutations.Add(mutations_list[ELVIS])

/obj/item/weapon/dnainjector/antielvis
	name = "\improper DNA injector (Anti-Elvis)"
	New()
		..()
		remove_mutations.Add(mutations_list[ELVIS])


code:
//In this file: C4 and Syndicate Bombs

/obj/item/weapon/c4
	name = "C-4"
	desc = "Used to put holes in specific areas without too much extra hole."
	gender = PLURAL
	icon = 'icons/obj/assemblies.dmi'
	icon_state = "plastic-explosive0"
	item_state = "plasticx"
	flags = NOBLUDGEON
	w_class = 2.0
	origin_tech = "syndicate=2"
	var/datum/wires/explosive/c4/wires = null
	var/timer = 10
	var/atom/target = null
	var/open_panel = 0
	var/image_overlay = null

/obj/item/weapon/c4/New()
	wires = new(src)
	image_overlay = image('icons/obj/assemblies.dmi', "plastic-explosive2")
	..()

/obj/item/weapon/c4/suicide_act(var/mob/user)
	user.visible_message("[user] activates the [src.name] and holds it above his head! It looks like \he's going out with a bang!")
	var/message_say = "FOR NO RIESEN!"
	if(user.mind)
		if(user.mind.special_role)
			var/role = lowertext(user.mind.special_role)
			if(role == "traitor" || role == "syndicate")
				message_say = "FOR THE SYNDICATE!"
			else if(role == "changeling")
				message_say = "FOR THE HIVE!"
			else if(role == "cultist")
				message_say = "FOR NAR-SIE!"
			else if(role == "revolutionary" || role == "head revolutionary")
				message_say = "VIVA LA REVOLUTION!"
	user.say(message_say)
	target = user
	message_admins("[key_name(user, user.client)](?) suicided with [src.name] at ([x],[y],[z] - JMP)",0,1)
	sleep(10)
	explode(get_turf(user))
	user.gib()

/obj/item/weapon/c4/attackby(var/obj/item/I, var/mob/user, params)
	if(istype(I, /obj/item/weapon/screwdriver))
		open_panel = !open_panel
		user << "You [open_panel ? "open" : "close"] the wire panel."
	else if(istype(I, /obj/item/weapon/wirecutters) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler ))
		wires.Interact(user)
	else
		..()

/obj/item/weapon/c4/attack_self(mob/user as mob)
	var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
	if(user.get_active_hand() == src)
		newtime = Clamp(newtime, 10, 60000)
		timer = newtime
		user << "Timer set for [timer] seconds."

/obj/item/weapon/c4/afterattack(atom/movable/target, mob/user, flag)
	if (!flag)
		return
	if (istype(target, /obj/item/weapon/storage/))
		return
	user << "Planting explosives..."
	if(ismob(target))
		add_logs(user, target, "tried to plant explosives on", object="[name]")
		user.visible_message("\red [user.name] is trying to plant some kind of explosive on [target.name]!")

	if(do_after(user, 50) && in_range(user, target))
		user.drop_item()
		src.target = target
		loc = null

		if (ismob(target))
			add_logs(user, target, "planted [name] on")
			user.visible_message("[user.name] finished planting an explosive on [target.name]!")
			message_admins("[key_name(user, user.client)](?) planted [src.name] on [key_name(target)](?) with [timer] second fuse",0,1)
			log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse")

		else
			message_admins("[key_name(user, user.client)](?) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1)
			log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")

		target.overlays += image_overlay
		user << "Bomb has been planted. Timer counting down from [timer]."
		spawn(timer*10)
			if(target && !target.gc_destroyed)
				explode(get_turf(target))
			else
				qdel(src)

/obj/item/weapon/c4/proc/explode(var/turf/location)
	location.ex_act(2, target)
	explosion(location,1,2,3)
	if(target)
		target.overlays -= image_overlay
	qdel(src)

/obj/item/weapon/c4/attack(mob/M as mob, mob/user as mob, def_zone)
	return


code:
/obj/item/weapon/extinguisher
	name = "fire extinguisher"
	desc = "A traditional red fire extinguisher."
	icon = 'icons/obj/items.dmi'
	icon_state = "fire_extinguisher0"
	item_state = "fire_extinguisher"
	hitsound = 'sound/weapons/smash.ogg'
	flags = CONDUCT
	throwforce = 10
	w_class = 3.0
	throw_speed = 2
	throw_range = 7
	force = 10
	m_amt = 90
	attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
	var/max_water = 50
	var/last_use = 1.0
	var/safety = 1
	var/sprite_name = "fire_extinguisher"
	var/power = 5 //Maximum distance launched water will travel
	var/precision = 0 //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row
	var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled

/obj/item/weapon/extinguisher/mini
	name = "pocket fire extinguisher"
	desc = "A light and compact fibreglass-framed model fire extinguisher."
	icon_state = "miniFE0"
	item_state = "miniFE"
	hitsound = null	//it is much lighter, after all.
	flags = null //doesn't CONDUCT
	throwforce = 2
	w_class = 2.0
	force = 3.0
	m_amt = 0
	max_water = 30
	sprite_name = "miniFE"

/obj/item/weapon/extinguisher/New()
	create_reagents(max_water)
	reagents.add_reagent("water", max_water)

/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
	safety = !safety
	src.icon_state = "[sprite_name][!safety]"
	src.desc = "The safety is [safety ? "on" : "off"]."
	user << "The safety is [safety ? "on" : "off"]."
	return

/obj/item/weapon/extinguisher/examine(mob/user as mob)
	..()
	if(reagents.total_volume)
		user << "It contains [round(reagents.total_volume)] units."
	else
		user << "It is empty."

/obj/item/weapon/extinguisher/proc/AttemptRefill(atom/target, mob/user)
	if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user))
		var/safety_save = safety
		safety = 1
		if(reagents.total_volume == reagents.maximum_volume)
			user << "\The [src] is already full!"
			safety = safety_save
			return 1
		var/obj/structure/reagent_dispensers/watertank/W = target
		var/transferred = W.reagents.trans_to(src, max_water)
		if(transferred > 0)
			user << "\The [src] has been refilled by [transferred] units"
			playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
			for(var/datum/reagent/water/R in reagents.reagent_list)
				R.cooling_temperature = cooling_power
		else
			user << "\The [W] is empty!"
		safety = safety_save
		return 1
	else
		return 0

/obj/item/weapon/extinguisher/afterattack(atom/target, mob/user , flag)
	//TODO; Add support for reagents in water.
	if(target.loc == user || !check_allowed_items(target))//No more spraying yourself when putting your extinguisher away
		return
	var/Refill = AttemptRefill(target, user)
	if(Refill)
		return
	if (!safety)
		if (src.reagents.total_volume < 1)
			usr << "\The [src] is empty."
			return

		if (world.time < src.last_use + 20)
			return

		src.last_use = world.time

		playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3)

		var/direction = get_dir(src,target)

		if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored)
			spawn(0)
				var/obj/B = usr.buckled
				var/movementdirection = turn(direction,180)
				step(B, movementdirection)
				sleep(1)
				step(B, movementdirection)
				sleep(1)
				step(B, movementdirection)
				sleep(1)
				step(B, movementdirection)
				sleep(2)
				step(B, movementdirection)
				sleep(2)
				step(B, movementdirection)
				sleep(3)
				step(B, movementdirection)
				sleep(3)
				step(B, movementdirection)
				sleep(3)
				step(B, movementdirection)

		else user.newtonian_move(turn(direction, 180))

		var/turf/T = get_turf(target)
		var/turf/T1 = get_step(T,turn(direction, 90))
		var/turf/T2 = get_step(T,turn(direction, -90))
		var/list/the_targets = list(T,T1,T2)
		if(precision)
			var/turf/T3 = get_step(T1, turn(direction, 90))
			var/turf/T4 = get_step(T2,turn(direction, -90))
			the_targets = list(T,T1,T2,T3,T4)

		for(var/a=0, a<5, a++)
			spawn(0)
				var/obj/effect/effect/water/W = PoolOrNew( /obj/effect/effect/water, get_turf(src) )
				var/turf/my_target = pick(the_targets)
				if(precision)
					the_targets -= my_target
				var/datum/reagents/R = new/datum/reagents(5)
				if(!W) return
				W.reagents = R
				R.my_atom = W
				if(!W || !src) return
				src.reagents.trans_to(W,1)
				for(var/b=0, b<power, b++)
					step_towards(W,my_target)
					if(!W || !W.reagents) return
					W.reagents.reaction(get_turf(W))
					for(var/atom/atm in get_turf(W))
						if(!W) return
						W.reagents.reaction(atm)
						if(isliving(atm)) //For extinguishing mobs on fire
							var/mob/living/M = atm
							M.ExtinguishMob()
					if(W.loc == my_target) break
					sleep(2)

	else
		return ..()


code:
/obj/item/weapon/flamethrower
	name = "flamethrower"
	desc = "You are a firestarter!"
	icon = 'icons/obj/flamethrower.dmi'
	icon_state = "flamethrowerbase"
	item_state = "flamethrower_0"
	flags = CONDUCT
	force = 3.0
	throwforce = 10.0
	throw_speed = 1
	throw_range = 5
	w_class = 3.0
	m_amt = 500
	origin_tech = "combat=1;plasmatech=1"
	var/status = 0
	var/throw_amount = 100
	var/lit = 0	//on or off
	var/operating = 0//cooldown
	var/obj/item/weapon/weldingtool/weldtool = null
	var/obj/item/device/assembly/igniter/igniter = null
	var/obj/item/weapon/tank/internals/plasma/ptank = null

/obj/item/weapon/flamethrower/Destroy()
	if(weldtool)
		qdel(weldtool)
	if(igniter)
		qdel(igniter)
	if(ptank)
		qdel(ptank)
	..()

/obj/item/weapon/flamethrower/process()
	if(!lit)
		SSobj.processing.Remove(src)
		return null
	var/turf/location = loc
	if(istype(location, /mob/))
		var/mob/M = location
		if(M.l_hand == src || M.r_hand == src)
			location = M.loc
	if(isturf(location)) //start a fire if possible
		location.hotspot_expose(700, 2)
	return

/obj/item/weapon/flamethrower/update_icon()
	overlays.Cut()
	if(igniter)
		overlays += "+igniter[status]"
	if(ptank)
		overlays += "+ptank"
	if(lit)
		overlays += "+lit"
		item_state = "flamethrower_1"
	else
		item_state = "flamethrower_0"
	return

/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, flag)
	if(flag) return // too close
	// Make sure our user is still holding us
	if(user && user.get_active_hand() == src)
		var/turf/target_turf = get_turf(target)
		if(target_turf)
			var/turflist = getline(user, target_turf)
			flame_turf(turflist)

/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob, params)
	if(user.stat || user.restrained() || user.lying)	return
	if(istype(W, /obj/item/weapon/wrench) && !status)//Taking this apart
		var/turf/T = get_turf(src)
		if(weldtool)
			weldtool.loc = T
			weldtool = null
		if(igniter)
			igniter.loc = T
			igniter = null
		if(ptank)
			ptank.loc = T
			ptank = null
		new /obj/item/stack/rods(T)
		qdel(src)
		return

	if(istype(W, /obj/item/weapon/screwdriver) && igniter && !lit)
		status = !status
		user << "[igniter] is now [status ? "secured" : "unsecured"]!"
		update_icon()
		return

	if(isigniter(W))
		var/obj/item/device/assembly/igniter/I = W
		if(I.secured)	return
		if(igniter)		return
		user.drop_item()
		I.loc = src
		igniter = I
		update_icon()
		return

	if(istype(W,/obj/item/weapon/tank/internals/plasma))
		if(ptank)
			user << "There appears to already be a plasma tank loaded in [src]!"
			return
		user.drop_item()
		ptank = W
		W.loc = src
		update_icon()
		return

	if(istype(W, /obj/item/device/analyzer) && ptank)
		atmosanalyzer_scan(ptank.air_contents, user)
	..()
	return

/obj/item/weapon/flamethrower/attack_self(mob/user as mob)
	if(user.stat || user.restrained() || user.lying)	return
	user.set_machine(src)
	if(!ptank)
		user << "Attach a plasma tank first!"
		return
	var/dat = text("<TT>Flamethrower ([lit ? "Lit" : "Unlit"])
\n Tank Pressure: [ptank.air_contents.return_pressure()]
\nAmount to throw: - - - [throw_amount] + + +
\nRemove plasmatank - Close</TT>")
	user << browse(dat, "window=flamethrower;size=600x300")
	onclose(user, "flamethrower")
	return

/obj/item/weapon/flamethrower/Topic(href,href_list[])
	if(href_list["close"])
		usr.unset_machine()
		usr << browse(null, "window=flamethrower")
		return
	if(usr.stat || usr.restrained() || usr.lying)	return
	usr.set_machine(src)
	if(href_list["light"])
		if(!ptank)	return
		if(!status)	return
		lit = !lit
		if(lit)
			SSobj.processing |= src
	if(href_list["amount"])
		throw_amount = throw_amount + text2num(href_list["amount"])
		throw_amount = max(50, min(5000, throw_amount))
	if(href_list["remove"])
		if(!ptank)	return
		usr.put_in_hands(ptank)
		ptank = null
		lit = 0
		usr.unset_machine()
		usr << browse(null, "window=flamethrower")
	for(var/mob/M in viewers(1, loc))
		if((M.client && M.machine == src))
			attack_self(M)
	update_icon()
	return

/obj/item/weapon/flamethrower/CheckParts()
	weldtool = locate(/obj/item/weapon/weldingtool) in contents
	igniter = locate(/obj/item/device/assembly/igniter) in contents
	update_icon()

//Called from turf.dm turf/dblclick
/obj/item/weapon/flamethrower/proc/flame_turf(turflist)
	if(!lit || operating)	return
	operating = 1
	var/turf/previousturf = get_turf(src)
	for(var/turf/simulated/T in turflist)
		if(!T.air)
			break
		if(T == previousturf)
			continue	//so we don't burn the tile we be standin on
		if(!T.CanAtmosPass(previousturf))
			break
		ignite_turf(T)
		sleep(1)
		previousturf = T
	operating = 0
	for(var/mob/M in viewers(1, loc))
		if((M.client && M.machine == src))
			attack_self(M)
	return

/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target)
	//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
	//Transfer 5% of current tank air contents to turf
	var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.05)
	air_transfer.toxins = air_transfer.toxins * 5
	target.assume_air(air_transfer)
	//Burn it based on transfered gas
	target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
	//location.hotspot_expose(1000,500,1)
	SSair.add_to_active(target, 0)
	return

/obj/item/weapon/flamethrower/full/New(var/loc)
	..()
	if(!weldtool)
		weldtool = new /obj/item/weapon/weldingtool(src)
	weldtool.status = 0
	if(!igniter)
		igniter = new /obj/item/device/assembly/igniter(src)
	igniter.secured = 0
	status = 1
	update_icon()

/obj/item/weapon/flamethrower/full/tank/New(var/loc)
	..()
	ptank = new /obj/item/weapon/tank/internals/plasma/full(src)
	update_icon()


code:
/* Gifts and wrapping paper
 * Contains:
 *		Gifts
 *		Wrapping Paper
 */

/*
 * Gifts
 */
/obj/item/weapon/a_gift
	name = "gift"
	desc = "PRESENTS!!!! eek!"
	icon = 'icons/obj/storage.dmi'
	icon_state = "giftcrate3"
	item_state = "gift1"

/obj/item/weapon/a_gift/New()
	..()
	pixel_x = rand(-10,10)
	pixel_y = rand(-10,10)
	icon_state = "giftcrate[rand(1,5)]"

/obj/item/weapon/a_gift/attack_self(mob/M as mob)
	if(M && M.mind && M.mind.special_role == "Santa")
		M << "You're supposed to be spreading gifts, not opening them yourself!"
		return

	var/gift_type_list = list(/obj/item/weapon/sord,
		/obj/item/weapon/storage/wallet,
		/obj/item/weapon/storage/photo_album,
		/obj/item/weapon/storage/box/snappops,
		/obj/item/weapon/storage/fancy/crayons,
		/obj/item/weapon/storage/backpack/holding,
		/obj/item/weapon/storage/belt/champion,
		/obj/item/weapon/soap/deluxe,
		/obj/item/weapon/pickaxe/diamond,
		/obj/item/weapon/pen/invisible,
		/obj/item/weapon/lipstick/random,
		/obj/item/weapon/grenade/smokebomb,
		/obj/item/weapon/grown/corncob,
		/obj/item/weapon/contraband/poster,
		/obj/item/weapon/contraband/poster/legit,
		/obj/item/weapon/book/manual/barman_recipes,
		/obj/item/weapon/book/manual/chef_recipes,
		/obj/item/weapon/bikehorn,
		/obj/item/weapon/beach_ball,
		/obj/item/weapon/beach_ball/holoball,
		/obj/item/weapon/banhammer,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,
		/obj/item/device/paicard,
		/obj/item/device/violin,
		/obj/item/weapon/storage/belt/utility/full,
		/obj/item/clothing/tie/horrible,
		/obj/item/clothing/suit/jacket/leather,
		/obj/item/clothing/suit/poncho,
		/obj/item/clothing/suit/poncho/green,
		/obj/item/clothing/suit/poncho/red)

	gift_type_list += typesof(/obj/item/clothing/head/collectable) - /obj/item/clothing/head/collectable
	gift_type_list += typesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/ammo) + /obj/item/toy) //All toys, except for abstract types and syndicate cards.

	var/gift_type = pick(gift_type_list)

	if(!ispath(gift_type,/obj/item))	return

	var/obj/item/I = new gift_type(M)
	M.unEquip(src, 1)
	M.put_in_hands(I)
	I.add_fingerprint(M)
	qdel(src)
	return

/*
 * Wrapping Paper
 */
/obj/item/stack/wrapping_paper
	name = "wrapping paper"
	desc = "You can use this to wrap items in."
	icon = 'icons/obj/items.dmi'
	icon_state = "wrap_paper"
	flags = NOBLUDGEON
	amount = 25
	max_amount = 25

/obj/item/stack/wrapping_paper/attack_self(mob/user)
	user << "You need to use it on a package that has already been wrapped!"


code:
#define EMPTY 1
#define WIRED 2
#define READY 3

/obj/item/weapon/grenade/chem_grenade
	name = "grenade"
	desc = "A custom made grenade."
	icon_state = "chemg"
	item_state = "flashbang"
	w_class = 2
	force = 2
	var/stage = EMPTY
	var/list/beakers = list()
	var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle)
	var/affected_area = 3
	var/obj/item/device/assembly_holder/nadeassembly = null
	var/assemblyattacher

/obj/item/weapon/grenade/chem_grenade/New()
	create_reagents(1000)
	stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.

/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
	display_timer = (stage == READY && !nadeassembly)	//show/hide the timer based on assembly state
	..()

/obj/item/weapon/grenade/chem_grenade/attack_self(mob/user)
	if(stage == READY &&  !active)
		if(nadeassembly)
			nadeassembly.attack_self(user)
		else if(clown_check(user))
			var/turf/bombturf = get_turf(src)
			var/area/A = get_area(bombturf)
			message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).")
			log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
			user << "You prime the [name]! [det_time / 10] second\s!"
			playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
			active = 1
			icon_state = initial(icon_state) + "_active"
			if(iscarbon(user))
				var/mob/living/carbon/C = user
				C.throw_mode_on()

			spawn(det_time)
				prime()

/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/weapon/screwdriver))
		if(stage == WIRED)
			if(beakers.len)
				stage_change(READY)
				user << "You lock the [initial(name)] assembly."
				playsound(loc, 'sound/items/Screwdriver.ogg', 25, -3)
			else
				user << "You need to add at least one beaker before locking the [initial(name)] assembly."
		else if(stage == READY && !nadeassembly)
			det_time = det_time == 50 ? 30 : 50	//toggle between 30 and 50
			user << "You modify the time delay. It's set for [det_time / 10] second\s."
		else if(stage == EMPTY)
			user << "You need to add an activation mechanism."

	else if(stage == WIRED && is_type_in_list(I, allowed_containers))
		if(beakers.len == 2)
			user << "[src] can not hold more containers."
			return
		else
			if(I.reagents.total_volume)
				user << "You add [I] to the [initial(name)] assembly."
				user.drop_item()
				I.loc = src
				beakers += I
			else
				user << "[I] is empty."

	else if(stage == EMPTY && istype(I, /obj/item/device/assembly_holder))
		var/obj/item/device/assembly_holder/A = I
		if(isigniter(A.a_left) == isigniter(A.a_right))	//Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
			return

		user.drop_item()
		nadeassembly = A
		A.master = src
		A.loc = src
		assemblyattacher = user.ckey

		stage_change(WIRED)
		user << "You add [A] to the [initial(name)] assembly!"

	else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
		var/obj/item/stack/cable_coil/C = I
		if (C.use(1))
			det_time = 50 // In case the cable_coil was removed and readded.
			stage_change(WIRED)
			user << "You rig the [initial(name)] assembly."
		else
			user << "You need one length of coil to wire the assembly."
			return

	else if(stage == READY && istype(I, /obj/item/weapon/wirecutters))
		stage_change(WIRED)
		user << "You unlock the [initial(name)] assembly."

	else if(stage == WIRED && istype(I, /obj/item/weapon/wrench))
		if(beakers.len)
			for(var/obj/O in beakers)
				O.loc = get_turf(src)
			beakers = list()
			user << "You open the [initial(name)] assembly and remove the payload."
			return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
		if(nadeassembly)
			nadeassembly.loc = get_turf(src)
			nadeassembly.master = null
			nadeassembly = null
		else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used.
			new /obj/item/stack/cable_coil(get_turf(src),1)
		stage_change(EMPTY)
		user << "You remove the activation mechanism from the [initial(name)] assembly."

/obj/item/weapon/grenade/chem_grenade/proc/stage_change(var/N)
	if(N)
		stage = N
	if(stage == EMPTY)
		name = "[initial(name)] casing"
		desc = "A do it yourself [initial(name)] casing!"
		icon_state = initial(icon_state)
	else if(stage == WIRED)
		name = "unsecured [initial(name)]"
		desc = "An unsecured [initial(name)] assembly."
		icon_state = "[initial(icon_state)]_ass"
	else if(stage == READY)
		name = initial(name)
		desc = initial(desc)
		icon_state = "[initial(icon_state)]_locked"

//assembly stuff
/obj/item/weapon/grenade/chem_grenade/receive_signal()
	prime()

/obj/item/weapon/grenade/chem_grenade/HasProximity(atom/movable/AM)
	if(nadeassembly)
		nadeassembly.HasProximity(AM)

/obj/item/weapon/grenade/chem_grenade/Crossed(atom/movable/AM)
	if(nadeassembly)
		nadeassembly.Crossed(AM)

/obj/item/weapon/grenade/chem_grenade/on_found(mob/finder)
	if(nadeassembly)
		nadeassembly.on_found(finder)

/obj/item/weapon/grenade/chem_grenade/prime()
	if(stage != READY)
		return

	var/has_reagents
	for(var/obj/item/I in beakers)
		if(I.reagents.total_volume)
			has_reagents = 1

	if(!has_reagents)
		playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
		return

	if(nadeassembly)
		var/mob/M = get_mob_by_ckey(assemblyattacher)
		var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
		var/turf/T = get_turf(src)
		var/area/A = get_area(T)
		message_admins("grenade primed by an assembly, attached by [M.key]/[M](?) and last touched by [last.key]/[last](?) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
		log_game("grenade primed by an assembly, attached by [M.key]/[M] and last touched by [last.key]/[last] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")

	playsound(loc, 'sound/effects/bamf.ogg', 50, 1)

	update_mob()

	mix_reagents()

	if(reagents.total_volume)	//The possible reactions didnt use up all reagents.
		var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
		steam.set_up(10, 0, get_turf(src))
		steam.attach(src)
		steam.start()

	var/list/viewable = view(affected_area, loc)
	var/list/accessible = can_flood_from(loc, affected_area)
	var/list/reactable = accessible
	var/mycontents = GetAllContents()
	for(var/turf/T in accessible)
		for(var/atom/A in T.GetAllContents())
			if(A in mycontents) continue
			if(!(A in viewable)) continue
			reactable |= A
	var/fraction = (reagents.total_volume/reactable.len) - reagents.total_volume
	for(var/atom/A in reactable)
		reagents.reaction(A, TOUCH, fraction)

	invisibility = INVISIBILITY_MAXIMUM		//Why am i doing this?
	spawn(50)		   //To make sure all reagents can work
		qdel(src)	   //correctly before deleting the grenade.

/obj/item/weapon/grenade/chem_grenade/proc/mix_reagents()
	var/total_temp
	for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
		G.reagents.trans_to(src, G.reagents.total_volume)
		total_temp += G.reagents.chem_temp
	reagents.chem_temp = total_temp

/obj/item/weapon/grenade/chem_grenade/proc/can_flood_from(myloc, maxrange)
	var/list/reachable = list(myloc)
	for(var/i=1; i<=maxrange; i++)
		for(var/turf/T in (orange(i, myloc) - orange(i-1, myloc)))
			if(T in reachable) continue
			for(var/turf/NT in orange(1, T))
				if(!(NT in reachable)) continue
				if(!(get_dir(T,NT) in cardinal)) continue
				if(!NT.CanAtmosPass(T)) continue
				reachable |= T
				break
	return reachable

//Large chem grenades accept slime cores and use the appropriately.
/obj/item/weapon/grenade/chem_grenade/large
	name = "large grenade"
	desc = "A custom made large grenade."
	icon_state = "large_grenade"
	allowed_containers = list(/obj/item/weapon/reagent_containers/glass,/obj/item/weapon/reagent_containers/food/condiment,
								/obj/item/weapon/reagent_containers/food/drinks)
	origin_tech = "combat=3;materials=3"
	affected_area = 4

/obj/item/weapon/grenade/chem_grenade/large/mix_reagents()
	for(var/obj/item/slime_extract/S in beakers)
		if(S.Uses)
			for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
				G.reagents.trans_to(S, G.reagents.total_volume)

			//If there is still a core (sometimes it's used up)
			//and there are reagents left, behave normally

			if(S && S.reagents && S.reagents.total_volume)
				S.reagents.trans_to(src,S.reagents.total_volume)
			return
	..()

	//I tried to just put it in the allowed_containers list but
	//if you do that it must have reagents.  If you're going to
	//make a special case you might as well do it explicitly. -Sayu
/obj/item/weapon/grenade/chem_grenade/large/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/slime_extract) && stage == WIRED)
		user << "You add [I] to the [initial(name)] assembly."
		user.drop_item()
		I.loc = src
		beakers += I
	else
		return ..()

/obj/item/weapon/grenade/chem_grenade/metalfoam
	name = "metal foam grenade"
	desc = "Used for emergency sealing of air breaches."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/metalfoam/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("aluminium", 30)
	B2.reagents.add_reagent("foaming_agent", 10)
	B2.reagents.add_reagent("pacid", 10)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/incendiary
	name = "incendiary grenade"
	desc = "Used for clearing rooms of living things."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/incendiary/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("aluminium", 25)
	B2.reagents.add_reagent("plasma", 25)
	B2.reagents.add_reagent("sacid", 25)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/antiweed
	name = "weedkiller grenade"
	desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/antiweed/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("plantbgone", 25)
	B1.reagents.add_reagent("potassium", 25)
	B2.reagents.add_reagent("phosphorus", 25)
	B2.reagents.add_reagent("sugar", 25)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/cleaner
	name = "cleaner grenade"
	desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/cleaner/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("fluorosurfactant", 40)
	B2.reagents.add_reagent("water", 40)
	B2.reagents.add_reagent("cleaner", 10)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/teargas
	name = "teargas grenade"
	desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/teargas/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("condensedcapsaicin", 25)
	B1.reagents.add_reagent("potassium", 25)
	B2.reagents.add_reagent("phosphorus", 25)
	B2.reagents.add_reagent("sugar", 25)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/pacid
	name = "acid grenade"
	desc = "Used for melting armoured opponents."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/pacid/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("pacid", 25)
	B1.reagents.add_reagent("potassium", 25)
	B2.reagents.add_reagent("phosphorus", 25)
	B2.reagents.add_reagent("sugar", 25)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/colorful
	name = "colorful grenade"
	desc = "Used for wide scale painting projects."
	stage = READY

/obj/item/weapon/grenade/chem_grenade/colorful/New()
	..()
	var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)

	B1.reagents.add_reagent("colorful_reagent", 25)
	B1.reagents.add_reagent("potassium", 25)
	B2.reagents.add_reagent("phosphorus", 25)
	B2.reagents.add_reagent("sugar", 25)

	beakers += B1
	beakers += B2

#undef EMPTY
#undef WIRED
#undef READY