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"
	actions_types = list(/datum/action/item_action/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()
	toggle_paddles()

/obj/item/weapon/defibrillator/attack_hand(mob/user)
	if(loc == user)
		if(slot_flags == SLOT_BACK)
			if(user.get_item_by_slot(slot_back) == src)
				ui_action_click()
			else
				user << "Put the defibrillator on your back first!"

		else if(slot_flags == SLOT_BELT)
			if(user.get_item_by_slot(slot_belt) == src)
				ui_action_click()
			else
				user << "Strap the defibrillator's belt on first!"
		return
	..()

/obj/item/weapon/defibrillator/MouseDrop(obj/over_object)
	if(ismob(src.loc))
		var/mob/M = src.loc
		if(istype(over_object, /obj/screen/inventory/hand))
			var/obj/screen/inventory/hand/H = over_object

			switch(H.slot_id)
				if(slot_r_hand)
					if(M.r_hand)
						return
					if(!M.unEquip(src))
						return
					M.put_in_r_hand(src)
				if(slot_l_hand)
					if(M.l_hand)
						return
					if(!M.unEquip(src))
						return
					M.put_in_l_hand(src)

/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
			if(!user.unEquip(W))
				return
			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)
	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()
	for(var/X in actions)
		var/datum/action/A = X
		A.UpdateButtonIcon()

/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_flags == SLOT_BACK && slot != slot_back) || (slot_flags == SLOT_BELT && slot != slot_belt))
		remove_paddles(user)
		update_icon()

/obj/item/weapon/defibrillator/item_action_slot_check(slot, mob/user)
	if(slot == user.getBackSlot())
		return 1

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

/obj/item/weapon/defibrillator/proc/deductcharge(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(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/item_action_slot_check(slot, mob/user)
	if(slot == user.getBeltSlot())
		return 1

/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/loaded/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
	var/req_defib = 1
	var/combat = 0 //If it penetrates armor and gives additional functionality

/obj/item/weapon/twohanded/shockpaddles/proc/recharge(var/time)
	if(req_defib || !time)
		return
	cooldown = 1
	update_icon()
	sleep(time)
	var/turf/T = get_turf(src)
	T.audible_message("[src] beeps: Unit is recharged.")
	playsound(T, 'sound/machines/defib_ready.ogg', 50, 0)
	cooldown = 0
	update_icon()

/obj/item/weapon/twohanded/shockpaddles/New(mainunit)
	..()
	if(check_defib_exists(mainunit, src) && req_defib)
		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.")
	if(req_defib)
		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)
	if(!req_defib)
		return ..()
	if(user)
		var/obj/item/weapon/twohanded/offhand/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(user)

/obj/item/weapon/twohanded/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/human/M, obj/O)
	if(!req_defib)
		return 1 //If it doesn't need a defib, just say it exists
	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

	if(busy)
		return
	if(req_defib && !defib.powered)
		user.visible_message("[defib] beeps: Unit is unpowered.")
		playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
		return
	if(!wielded)
		if(isrobot(user))
			user << "You must activate the paddles in your active module before you can use them on someone!"
		else
			user << "You need to wield the paddles in both hands before you can use them on someone!"
		return
	if(cooldown)
		if(req_defib)
			user << "[defib] is recharging!"
		else
			user << "[src] are recharging!"
		return
	if(!ishuman(M))
		if(req_defib)
			user << "The instructions on [defib] don't mention how to revive that..."
		else
			user << "You aren't sure how to revive that..."
		return
	else
		var/mob/living/carbon/human/H = M
		if(user.a_intent == "disarm")
			if(req_defib && defib.safety)
				return
			if(!req_defib && !combat)
				return
			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", src)
			if(req_defib)
				defib.deductcharge(revivecost)
				cooldown = 1
			busy = 0
			update_icon()
			if(req_defib)
				defib.cooldowncheck(user)
			else
				recharge(60)
			return
		if(user.zone_selected == "chest")
			if(user.a_intent == "harm")
				if(req_defib && defib.safety)
					return
				if(!req_defib && !combat)
					return
				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)
					if(req_defib)
						T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...")
					else
						user.audible_message("[src] let out an urgent beep.")
					if(do_after(user, 30, target = M)) //Takes longer due to overcharging
						if(!M)
							busy = 0
							update_icon()
							return
						if(M && 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", defib)
						M.Weaken(5)
						M.Jitter(100)
						if(req_defib)
							defib.deductcharge(revivecost)
							cooldown = 1
						busy = 0
						update_icon()
						if(!req_defib)
							recharge(60)
						if(req_defib && (defib.cooldowncheck(user)))
							return
				busy = 0
				update_icon()
				return
			if(!H.suiciding && !(H.disabilities & NOCLONE))
				H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src)

			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 = 1200 //past this much time the patient is unrecoverable (in deciseconds)
				var/tloss = 600 //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((!src.combat && !req_defib) || (req_defib && !defib.combat))
								user.audible_message("[req_defib ? "[defib]" : "[src]"] 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.stat == DEAD)
						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)
						total_brute	= H.getBruteLoss()
						total_burn	= H.getFireLoss()

						var/failed = null

						if (H.suiciding || (H.disabilities & NOCLONE))
							failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile."
						else if (tplus > tlimit)
							failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile."
						else if (!H.getorgan(/obj/item/organ/internal/heart))
							failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing."
						else if(total_burn >= 180 || total_brute >= 180)
							failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile."
						else if(H.get_ghost())
							failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful."
						else
							var/obj/item/organ/internal/brain/BR = H.getorgan(/obj/item/organ/internal/brain)
							if(!BR || BR.damaged_brain)
								failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile."

						if(failed)
							user.visible_message(failed)
							playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
						else
							//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, 0)
							else
								var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
								var/mobhealth = H.health
								H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage), 0)
								H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage), 0)
								H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage), 0)
								H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage), 0)
							user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.")
							playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
							H.revive()
							H.emote("gasp")
							if(tplus > tloss)
								H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
							add_logs(user, M, "revived", defib)
						if(req_defib)
							defib.deductcharge(revivecost)
							cooldown = 1
						update_icon()
						if(req_defib)
							defib.cooldowncheck(user)
						else
							recharge(60)
					else if(H.heart_attack)
						H.heart_attack = 0
						user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.")
						playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
					else
						user.visible_message("[req_defib ? "[defib]" : "[src]"] 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

/obj/item/weapon/twohanded/shockpaddles/syndicate
	name = "syndicate defibrillator paddles"
	desc = "A pair of paddles used to revive deceased operatives. It possesses both the ability to penetrate armor and to deliver powerful shocks offensively."
	combat = 1
	icon = 'icons/obj/weapons.dmi'
	icon_state = "defibpaddles0"
	item_state = "defibpaddles0"
	req_defib = 0


code:
/obj/item/weapon/storage/pill_bottle/dice
	name = "bag of dice"
	desc = "Contains all the luck you'll ever need."
	icon = 'icons/obj/dice.dmi'
	icon_state = "dicebag"

/obj/item/weapon/storage/pill_bottle/dice/New()
	..()
	var/special_die = pick("1","2","fudge","00","100")
	if(special_die == "1")
		new /obj/item/weapon/dice/d1(src)
	if(special_die == "2")
		new /obj/item/weapon/dice/d2(src)
	new /obj/item/weapon/dice/d4(src)
	new /obj/item/weapon/dice/d6(src)
	if(special_die == "fudge")
		new /obj/item/weapon/dice/fudge(src)
	new /obj/item/weapon/dice/d8(src)
	new /obj/item/weapon/dice/d10(src)
	if(special_die == "00")
		new /obj/item/weapon/dice/d00(src)
	new /obj/item/weapon/dice/d12(src)
	new /obj/item/weapon/dice/d20(src)
	if(special_die == "100")
		new /obj/item/weapon/dice/d100(src)

/obj/item/weapon/dice //depreciated d6, use /obj/item/weapon/dice/d6 if you actually want a d6
	name = "die"
	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
	var/list/special_faces = list() //entries should match up to sides var if used

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

/obj/item/weapon/dice/d1
	name = "d1"
	desc = "A die with one side. Deterministic!"
	icon_state = "d1"
	sides = 1

/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/d6
	name = "d6"

/obj/item/weapon/dice/fudge
	name = "fudge die"
	desc = "A die with six sides but only three results. Is this a plus or a minus? Your mind is drawing a blank..."
	sides = 3 //shhh
	icon_state = "fudge"
	special_faces = list("minus","blank","plus")

/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/d100
	name = "d100"
	desc = "A die with one hundred sides! Probably not fairly weighted..."
	icon_state = "d100"
	sides = 100

/obj/item/weapon/dice/d100/update_icon()
	return

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

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

/obj/item/weapon/dice/proc/diceroll(mob/user)
	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(special_faces.len == sides)
		result = special_faces[result]
	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] rolling.")
	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(mob/living/carbon/human/H)
	if(istype(H) && !H.shoes)
		if(PIERCEIMMUNE 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]"

license: mit


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
	origin_tech = "biotech=1"

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

	var/list/add_mutations_static = list()
	var/list/remove_mutations_static = list()

	var/used = 0

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

/obj/item/weapon/dnainjector/proc/prepare()
	for(var/mut_key in add_mutations_static)
		add_mutations.Add(mutations_list[mut_key])
	for(var/mut_key in remove_mutations_static)
		remove_mutations.Add(mutations_list[mut_key])

/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
	prepare()

	if(M.has_dna() && !(M.disabilities & NOCLONE))
		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"])
				M.updateappearance(mutations_overlay_update=1)
		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
	if(used)
		user << "This injector is used up!"
		return
	if(ishuman(target))
		var/mob/living/carbon/human/humantarget = target
		if (!humantarget.can_inject(user, 1))
			return
	add_logs(user, target, "attempted to inject", src)

	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", src)

	inject(target, user)	//Now we actually do the heavy lifting.
	used = 1
	icon_state = "dnainjector0"
	desc += " This one is used up."

/obj/item/weapon/dnainjector/antihulk
	name = "\improper DNA injector (Anti-Hulk)"
	desc = "Cures green skin."
	remove_mutations_static = 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."
	add_mutations_static = list(HULK)

/obj/item/weapon/dnainjector/xraymut
	name = "\improper DNA injector (Xray)"
	desc = "Finally you can see what the Captain does."
	add_mutations_static = list(XRAY)

/obj/item/weapon/dnainjector/antixray
	name = "\improper DNA injector (Anti-Xray)"
	desc = "It will make you see harder."
	remove_mutations_static = list(XRAY)

/////////////////////////////////////
/obj/item/weapon/dnainjector/antiglasses
	name = "\improper DNA injector (Anti-Glasses)"
	desc = "Toss away those glasses!"
	remove_mutations_static = list(BADSIGHT)

/obj/item/weapon/dnainjector/glassesmut
	name = "\improper DNA injector (Glasses)"
	desc = "Will make you need dorkish glasses."
	add_mutations_static = list(BADSIGHT)

/obj/item/weapon/dnainjector/epimut
	name = "\improper DNA injector (Epi.)"
	desc = "Shake shake shake the room!"
	add_mutations_static = list(EPILEPSY)

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

/obj/item/weapon/dnainjector/coughmut
	name = "\improper DNA injector (Cough)"
	desc = "Will bring forth a sound of horror from your throat."
	add_mutations_static = list(COUGH)

/obj/item/weapon/dnainjector/antidwarf
	name = "\improper DNA injector (Anti-Dwarfism)"
	desc = "Helps you grow big and strong."
	remove_mutations_static = list(DWARFISM)

/obj/item/weapon/dnainjector/dwarf
	name = "\improper DNA injector (Dwarfism)"
	desc = "Its a small world after all."
	add_mutations_static = list(DWARFISM)

/obj/item/weapon/dnainjector/clumsymut
	name = "\improper DNA injector (Clumsy)"
	desc = "Makes clown minions."
	add_mutations_static = list(CLOWNMUT)

/obj/item/weapon/dnainjector/anticlumsy
	name = "\improper DNA injector (Anti-Clumy)"
	desc = "Apply this for Security Clown."
	remove_mutations_static = list(CLOWNMUT)

/obj/item/weapon/dnainjector/antitour
	name = "\improper DNA injector (Anti-Tour.)"
	desc = "Will cure tourrets."
	remove_mutations_static = list(TOURETTES)

/obj/item/weapon/dnainjector/tourmut
	name = "\improper DNA injector (Tour.)"
	desc = "Gives you a nasty case off tourrets."
	add_mutations_static = list(TOURETTES)

/obj/item/weapon/dnainjector/stuttmut
	name = "\improper DNA injector (Stutt.)"
	desc = "Makes you s-s-stuttterrr"
	add_mutations_static = list(NERVOUS)

/obj/item/weapon/dnainjector/antistutt
	name = "\improper DNA injector (Anti-Stutt.)"
	desc = "Fixes that speaking impairment."
	remove_mutations_static = list(NERVOUS)

/obj/item/weapon/dnainjector/antifire
	name = "\improper DNA injector (Anti-Fire)"
	desc = "Cures fire."
	remove_mutations_static = list(COLDRES)

/obj/item/weapon/dnainjector/firemut
	name = "\improper DNA injector (Fire)"
	desc = "Gives you fire."
	add_mutations_static = list(COLDRES)

/obj/item/weapon/dnainjector/blindmut
	name = "\improper DNA injector (Blind)"
	desc = "Makes you not see anything."
	add_mutations_static = list(BLINDMUT)

/obj/item/weapon/dnainjector/antiblind
	name = "\improper DNA injector (Anti-Blind)"
	desc = "ITS A MIRACLE!!!"
	remove_mutations_static = list(BLINDMUT)

/obj/item/weapon/dnainjector/antitele
	name = "\improper DNA injector (Anti-Tele.)"
	desc = "Will make you not able to control your mind."
	remove_mutations_static = list(TK)

/obj/item/weapon/dnainjector/telemut
	name = "\improper DNA injector (Tele.)"
	desc = "Super brain man!"
	add_mutations_static = 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?"
	add_mutations_static = list(DEAFMUT)

/obj/item/weapon/dnainjector/antideaf
	name = "\improper DNA injector (Anti-Deaf)"
	desc = "Will make you hear once more."
	remove_mutations_static = list(DEAFMUT)

/obj/item/weapon/dnainjector/h2m
	name = "\improper DNA injector (Human > Monkey)"
	desc = "Will make you a flea bag."
	add_mutations_static = list(RACEMUT)

/obj/item/weapon/dnainjector/m2h
	name = "\improper DNA injector (Monkey > Human)"
	desc = "Will make you...less hairy."
	remove_mutations_static = list(RACEMUT)

/obj/item/weapon/dnainjector/antichameleon
	name = "\improper DNA injector (Anti-Chameleon)"
	remove_mutations_static = list(CHAMELEON)

/obj/item/weapon/dnainjector/chameleonmut
	name = "\improper DNA injector (Chameleon)"
	add_mutations_static = list(CHAMELEON)

/obj/item/weapon/dnainjector/antiwacky
	name = "\improper DNA injector (Anti-Wacky)"
	remove_mutations_static = list(WACKY)

/obj/item/weapon/dnainjector/wackymut
	name = "\improper DNA injector (Wacky)"
	add_mutations_static = list(WACKY)

/obj/item/weapon/dnainjector/antimute
	name = "\improper DNA injector (Anti-Mute)"
	remove_mutations_static = list(MUT_MUTE)

/obj/item/weapon/dnainjector/mutemut
	name = "\improper DNA injector (Mute)"
	add_mutations_static = list(MUT_MUTE)

/obj/item/weapon/dnainjector/antismile
	name = "\improper DNA injector (Anti-Smile)"
	remove_mutations_static = list(SMILE)

/obj/item/weapon/dnainjector/smilemut
	name = "\improper DNA injector (Smile)"
	add_mutations_static = list(SMILE)

/obj/item/weapon/dnainjector/unintelligablemut
	name = "\improper DNA injector (Unintelligable)"
	add_mutations_static = list(UNINTELLIGABLE)

/obj/item/weapon/dnainjector/antiunintelligable
	name = "\improper DNA injector (Anti-Unintelligable)"
	remove_mutations_static = list(UNINTELLIGABLE)

/obj/item/weapon/dnainjector/swedishmut
	name = "\improper DNA injector (Swedish)"
	add_mutations_static = list(SWEDISH)

/obj/item/weapon/dnainjector/antiswedish
	name = "\improper DNA injector (Anti-Swedish)"
	remove_mutations_static = list(SWEDISH)

/obj/item/weapon/dnainjector/chavmut
	name = "\improper DNA injector (Chav)"
	add_mutations_static = list(CHAV)

/obj/item/weapon/dnainjector/antichav
	name = "\improper DNA injector (Anti-Chav)"
	remove_mutations_static = list(CHAV)

/obj/item/weapon/dnainjector/elvismut
	name = "\improper DNA injector (Elvis)"
	add_mutations_static = list(ELVIS)

/obj/item/weapon/dnainjector/antielvis
	name = "\improper DNA injector (Anti-Elvis)"
	remove_mutations_static = list(ELVIS)

/obj/item/weapon/dnainjector/lasereyesmut
	name = "\improper DNA injector (Laser Eyes)"
	add_mutations_static = list(LASEREYES)

/obj/item/weapon/dnainjector/antilasereyes
	name = "\improper DNA injector (Anti-Laser Eyes)"
	remove_mutations_static = list(LASEREYES)

/obj/item/weapon/dnainjector/timed
	var/duration = 600

/obj/item/weapon/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
	prepare()

	if(M.has_dna() && !(M.disabilities & NOCLONE))
		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]"
		var/endtime = world.time+duration
		for(var/datum/mutation/human/HM in remove_mutations)
			if(HM.name == RACEMUT)
				if(ishuman(M))
					continue
				M = HM.force_lose(M)
			else
				HM.force_lose(M)
		for(var/datum/mutation/human/HM in add_mutations)
			if((HM in M.dna.mutations) && !(M.dna.temporary_mutations[HM.name]))
				continue //Skip permanent mutations we already have.
			if(HM.name == RACEMUT && ishuman(M))
				message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)")
				log_msg += " (MONKEY)"
				M = HM.force_give(M)
			else
				HM.force_give(M)
			M.dna.temporary_mutations[HM.name] = endtime
		if(fields)
			if(fields["name"] && fields["UE"] && fields["blood_type"])
				if(!M.dna.previous["name"])
					M.dna.previous["name"] = M.real_name
				if(!M.dna.previous["UE"])
					M.dna.previous["UE"] = M.dna.unique_enzymes
				if(!M.dna.previous["blood_type"])
					M.dna.previous["blood_type"] = M.dna.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"]
				M.dna.temporary_mutations[UE_CHANGED] = endtime
			if(fields["UI"])	//UI+UE
				if(!M.dna.previous["UI"])
					M.dna.previous["UI"] = M.dna.uni_identity
				M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
				M.updateappearance(mutations_overlay_update=1)
				M.dna.temporary_mutations[UI_CHANGED] = endtime
		log_attack(log_msg)
	else
		user << "It appears that [M] does not have compatible DNA."
		return

/obj/item/weapon/dnainjector/timed/hulk
	name = "\improper DNA injector (Hulk)"
	desc = "This will make you big and strong, but give you a bad skin condition."
	add_mutations_static = list(HULK)

/obj/item/weapon/dnainjector/timed/h2m
	name = "\improper DNA injector (Human > Monkey)"
	desc = "Will make you a flea bag."
	add_mutations_static = list(RACEMUT)


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
	origin_tech = "syndicate=2"
	var/timer = 10
	var/atom/target = null
	var/open_panel = 0
	var/image_overlay = null

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

/obj/item/weapon/c4/Destroy()
	qdel(wires)
	wires = null
	target = null
	return ..()

/obj/item/weapon/c4/suicide_act(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 RAISIN!"
	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!"
			else if(user.mind.gang_datum)
				message_say = "[uppertext(user.mind.gang_datum.name)] RULES!"
	user.say(message_say)
	target = user
	message_admins("[key_name_admin(user)](?) (FLW) suicided with [src.name] at ([x],[y],[z] - JMP)",0,1)
	message_admins("[key_name(user)] suicided with [src.name] at ([x],[y],[z])")
	sleep(10)
	explode(get_turf(user))
	user.gib()

/obj/item/weapon/c4/attackby(obj/item/I, 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(is_wire_tool(I))
		wires.interact(user)
	else
		..()

/obj/item/weapon/c4/attack_self(mob/user)
	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/AM, mob/user, flag)
	if (!flag)
		return
	if (ismob(AM))
		return
	if(loc == AM)
		return
	if((istype(AM, /obj/item/weapon/storage/)) && !((istype(AM, /obj/item/weapon/storage/secure)) || (istype(AM, /obj/item/weapon/storage/lockbox)))) //If its storage but not secure storage OR a lockbox, then place it inside.
		return
	if((istype(AM,/obj/item/weapon/storage/secure)) || (istype(AM, /obj/item/weapon/storage/lockbox)))
		var/obj/item/weapon/storage/secure/S = AM
		if(!S.locked) //Literal hacks, this works for lockboxes despite incorrect type casting, because they both share the locked var. But if its unlocked, place it inside, otherwise PLANTING C4!
			return

	user << "You start planting the bomb..."

	if(do_after(user, 50, target = AM))
		if(!user.unEquip(src))
			return
		src.target = AM
		loc = null

		message_admins("[key_name_admin(user)](?) (FLW) 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 << "You plant the bomb. Timer counting down from [timer]."
		spawn(timer*10)
			explode()

/obj/item/weapon/c4/proc/explode()
	if(qdeleted(src))
		return
	var/turf/location
	if(target)
		if(!qdeleted(target))
			location = get_turf(target)
			target.overlays -= image_overlay
	else
		location = get_turf(src)
	if(location)
		location.ex_act(2, target)
		explosion(location,0,0,3)
	qdel(src)

/obj/item/weapon/c4/attack(mob/M, mob/user, 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
	throw_speed = 2
	throw_range = 7
	force = 10
	materials = list(MAT_METAL=90)
	attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
	var/max_water = 50
	var/last_use = 1
	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
	force = 3
	materials = list()
	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)
	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)
	..()
	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/particle_effect/water/W = PoolOrNew( /obj/effect/particle_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/A in get_turf(W))
						if(!W) return
						W.reagents.reaction(A)
					if(W.loc == my_target) break
					sleep(2)

	else
		return ..()

/obj/item/weapon/extinguisher/AltClick(mob/user)
	EmptyExtinguisher(user)

/obj/item/weapon/extinguisher/proc/EmptyExtinguisher(var/mob/user)
	if(loc == user && reagents.total_volume)
		reagents.clear_reagents()
		user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] using its release valve.")
	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
	throwforce = 10
	throw_speed = 1
	throw_range = 5
	w_class = 3
	materials = list(MAT_METAL=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
	var/warned_admins = 0 //for the message_admins() when lit

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

/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)
			add_logs(user, target, "flamethrowered", src, "at [target.x],[target.y],[target.z]")
			flame_turf(turflist)

/obj/item/weapon/flamethrower/attackby(obj/item/W, mob/user, 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
		if(!user.unEquip(W))
			return
		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
		if(!user.unEquip(W))
			return
		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)
	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(!warned_admins)
				message_admins("[key_name_admin(usr)]? (FLW) has lit a flamethrower.")
				warned_admins = 1
	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
	weldtool.status = 0
	igniter.secured = 0
	status = 1
	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/T in turflist)
		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, release_amount = 0.05)
	//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(release_amount)
	if(air_transfer.gases["plasma"])
		air_transfer.gases["plasma"][MOLES] *= 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()

/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
	if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15))
		owner.visible_message("[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!")
		var/target_turf = get_turf(owner)
		ignite_turf(target_turf, 100)
		qdel(ptank)
		return 1 //It hit the flamethrower, not them


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"
	burn_state = FLAMMABLE

/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/suicide_act(mob/user)
	user.visible_message("[user] peeks inside the [src.name] and cries \himself to death! It looks like they were on the naughty list...")
	return (BRUTELOSS)

/obj/item/weapon/a_gift/attack_self(mob/M)
	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/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/poster/contraband,
		/obj/item/weapon/poster/legit,
		/obj/item/weapon/book/manual/barman_recipes,
		/obj/item/weapon/book/manual/chef_recipes,
		/obj/item/weapon/bikehorn,
		/obj/item/toy/beach_ball,
		/obj/item/toy/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/instrument/violin,
		/obj/item/device/instrument/guitar,
		/obj/item/weapon/storage/belt/utility/full,
		/obj/item/clothing/tie/horrible,
		/obj/item/clothing/suit/jacket/leather,
		/obj/item/clothing/suit/jacket/leather/overcoat,
		/obj/item/clothing/suit/poncho,
		/obj/item/clothing/suit/poncho/green,
		/obj/item/clothing/suit/poncho/red,
		/obj/item/clothing/suit/snowman,
		/obj/item/clothing/head/snowman)

	gift_type_list += subtypesof(/obj/item/clothing/head/collectable)
	gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/figure + /obj/item/toy/ammo)) //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


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_admin(usr)]? (FLW) 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)
				if(!user.unEquip(I))
					return
				user << "You add [I] to the [initial(name)] assembly."
				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
		if(!user.unEquip(I))
			return

		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(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/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 || !reagents)
		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 [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
		log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(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)

	var/turf/DT = get_turf(src)
	var/area/DA = get_area(DT)
	log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")

	update_mob()

	mix_reagents()

	if(reagents.total_volume)	//The possible reactions didnt use up all reagents, so we spread it around.
		var/datum/effect_system/steam_spread/steam = new /datum/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
		if(!reactable.len) //Nothing to react with. Probably means we're in nullspace.
			qdel(src)
			return
		var/fraction = 1/reactable.len
		for(var/atom/A in reactable)
			reagents.reaction(A, TOUCH, fraction)

	qdel(src)

/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/turf/myturf = get_turf(myloc)
	var/list/reachable = list(myloc)
	for(var/i=1; i<=maxrange; i++)
		var/list/turflist = list()
		for(var/turf/T in (orange(i, myloc) - orange(i-1, myloc)))
			turflist |= T
		for(var/turf/T in turflist)
			if( !(get_dir(T,myloc) in cardinal) && (abs(T.x - myturf.x) == abs(T.y - myturf.y) ))
				turflist.Remove(T)
				turflist.Add(T) // we move the purely diagonal turfs to the end of the list.
		for(var/turf/T in turflist)
			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)
		if(!user.unEquip(I))
			return
		user << "You add [I] to the [initial(name)] assembly."
		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("facid", 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("phosphorus", 25)
	B2.reagents.add_reagent("stable_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/large/B1 = new(src)
	var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)

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

	beakers += B1
	beakers += B2

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

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

	B1.reagents.add_reagent("facid", 290)
	B1.reagents.add_reagent("potassium", 10)
	B2.reagents.add_reagent("phosphorus", 10)
	B2.reagents.add_reagent("sugar", 10)
	B2.reagents.add_reagent("facid", 280)

	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

/obj/item/weapon/grenade/chem_grenade/clf3
	name = "clf3 grenade"
	desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas."
	stage = READY

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

	B1.reagents.add_reagent("fluorosurfactant", 250)
	B1.reagents.add_reagent("clf3", 50)
	B2.reagents.add_reagent("water", 250)
	B2.reagents.add_reagent("clf3", 50)

	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/bioterrorfoam
	name = "Bio terror foam grenade"
	desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin"
	stage = READY

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

	B1.reagents.add_reagent("cryptobiolin", 75)
	B1.reagents.add_reagent("water", 50)
	B1.reagents.add_reagent("mutetoxin", 50)
	B1.reagents.add_reagent("spore", 75)
	B1.reagents.add_reagent("itching_powder", 50)
	B2.reagents.add_reagent("fluorosurfactant", 150)
	B2.reagents.add_reagent("mutagen", 150)
	beakers += B1
	beakers += B2

/obj/item/weapon/grenade/chem_grenade/tuberculosis
 	name = "Fungal tuberculosis grenade"
 	desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
 	stage = READY

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

	B1.reagents.add_reagent("potassium", 50)
	B1.reagents.add_reagent("phosphorus", 50)
	B1.reagents.add_reagent("fungalspores", 200)
	B2.reagents.add_reagent("blood", 250)
	B2.reagents.add_reagent("sugar", 50)

	beakers += B1
	beakers += B2

#undef EMPTY
#undef WIRED
#undef READY


code:
////////////////////
//Clusterbang
////////////////////
/obj/item/weapon/grenade/clusterbuster
	desc = "Use of this weapon may constiute a war crime in your area, consult your local captain."
	name = "clusterbang"
	icon = 'icons/obj/grenade.dmi'
	icon_state = "clusterbang"
	var/payload = /obj/item/weapon/grenade/flashbang/cluster

/obj/item/weapon/grenade/clusterbuster/prime()
	update_mob()
	var/numspawned = rand(4,8)
	var/again = 0

	for(var/more = numspawned,more > 0,more--)
		if(prob(35))
			again++
			numspawned--

	for(var/loop = again ,loop > 0, loop--)
		new /obj/item/weapon/grenade/clusterbuster/segment(loc, payload)//Creates 'segments' that launches a few more payloads

	new /obj/effect/payload_spawner(loc, payload, numspawned)//Launches payload

	playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)

	qdel(src)

//////////////////////
//Clusterbang segment
//////////////////////
/obj/item/weapon/grenade/clusterbuster/segment
	desc = "A smaller segment of a clusterbang. Better run."
	name = "clusterbang segment"
	icon = 'icons/obj/grenade.dmi'
	icon_state = "clusterbang_segment"

/obj/item/weapon/grenade/clusterbuster/segment/New(var/loc, var/payload_type = /obj/item/weapon/grenade/flashbang/cluster)
	..()
	icon_state = "clusterbang_segment_active"
	payload = payload_type
	active = 1
	walk_away(src,loc,rand(1,4))
	spawn(rand(15,60))
		prime()

/obj/item/weapon/grenade/clusterbuster/segment/prime()

	new /obj/effect/payload_spawner(loc, payload, rand(4,8))

	playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)

	qdel(src)

//////////////////////////////////
//The payload spawner effect
/////////////////////////////////
/obj/effect/payload_spawner/New(var/turf/newloc,var/type, var/numspawned as num)

	for(var/loop = numspawned ,loop > 0, loop--)
		var/obj/item/weapon/grenade/P = new type(loc)
		P.active = 1
		walk_away(P,loc,rand(1,4))

		spawn(rand(15,60))
			if(P && !qdeleted(P))
				P.prime()
			qdel(src)

//////////////////////////////////
//Custom payload clusterbusters
/////////////////////////////////
/obj/item/weapon/grenade/flashbang/cluster
	icon_state = "flashbang_active"

/obj/item/weapon/grenade/clusterbuster/emp
	name = "Electromagnetic Storm"
	payload = /obj/item/weapon/grenade/empgrenade

/obj/item/weapon/grenade/clusterbuster/smoke
	name = "Ninja Vanish"
	payload = /obj/item/weapon/grenade/smokebomb

/obj/item/weapon/grenade/clusterbuster/metalfoam
	name = "Instant Concrete"
	payload = /obj/item/weapon/grenade/chem_grenade/metalfoam

/obj/item/weapon/grenade/clusterbuster/inferno
	name = "Inferno"
	payload = /obj/item/weapon/grenade/chem_grenade/incendiary

/obj/item/weapon/grenade/clusterbuster/antiweed
	name = "RoundDown"
	payload = /obj/item/weapon/grenade/chem_grenade/antiweed

/obj/item/weapon/grenade/clusterbuster/cleaner
	name = "Mr. Proper"
	payload = /obj/item/weapon/grenade/chem_grenade/cleaner

/obj/item/weapon/grenade/clusterbuster/teargas
	name = "Oignon Grenade"
	payload = /obj/item/weapon/grenade/chem_grenade/teargas

/obj/item/weapon/grenade/clusterbuster/facid
	name = "Aciding Rain"
	payload = /obj/item/weapon/grenade/chem_grenade/facid

/obj/item/weapon/grenade/clusterbuster/syndieminibomb
	name = "SyndiWrath"
	payload = /obj/item/weapon/grenade/syndieminibomb

/obj/item/weapon/grenade/clusterbuster/spawner_manhacks
	name = "iViscerator"
	payload = /obj/item/weapon/grenade/spawnergrenade/manhacks

/obj/item/weapon/grenade/clusterbuster/spawner_spesscarp
	name = "Invasion of the Space Carps"
	payload = /obj/item/weapon/grenade/spawnergrenade/spesscarp

/obj/item/weapon/grenade/clusterbuster/soap
	name = "Slipocalypse"
	payload = /obj/item/weapon/grenade/spawnergrenade/syndiesoap

/obj/item/weapon/grenade/clusterbuster/clf3
	name = "WELCOME TO HELL"
	payload = /obj/item/weapon/grenade/chem_grenade/clf3


code:
/obj/item/weapon/grenade/empgrenade
	name = "classic EMP grenade"
	desc = "It is designed to wreak havok on electronic systems."
	icon_state = "emp"
	item_state = "emp"
	origin_tech = "materials=2;magnets=3"

/obj/item/weapon/grenade/empgrenade/prime()
	update_mob()
	empulse(src, 4, 10)
	qdel(src)


code:
/obj/item/weapon/grenade/flashbang
	name = "flashbang"
	icon_state = "flashbang"
	item_state = "flashbang"
	origin_tech = "materials=2;combat=1"

/obj/item/weapon/grenade/flashbang/prime()
	update_mob()
	var/flashbang_turf = get_turf(src)
	if(!flashbang_turf)
		return
	for(var/mob/living/M in get_hearers_in_view(7, flashbang_turf))
		bang(get_turf(M), M)

	for(var/obj/effect/blob/B in get_hear(8,flashbang_turf))     		//Blob damage here
		var/damage = round(40/(get_dist(B,get_turf(src))+1))
		B.take_damage(damage, BURN)
	qdel(src)

/obj/item/weapon/grenade/flashbang/proc/bang(turf/T , mob/living/M)
	M.show_message("BANG", 2)
	playsound(loc, 'sound/weapons/flashbang.ogg', 100, 1)

//Checking for protection
	var/ear_safety = M.check_ear_prot()
	var/distance = max(1,get_dist(src,T))

//Flash
	if(M.weakeyes)
		M.visible_message("[M] screams and collapses!")
		M << "AAAAGH!"
		M.Weaken(15) //hella stunned
		M.Stun(15)
		M.adjust_eye_damage(8)

	if(M.flash_eyes(affect_silicon = 1))
		M.Stun(max(10/distance, 3))
		M.Weaken(max(10/distance, 3))

//Bang
	if((loc == M) || loc == M.loc)//Holding on person or being exactly where lies is significantly more dangerous and voids protection
		M.Stun(10)
		M.Weaken(10)
	if(!ear_safety)
		M << sound('sound/weapons/flash_ring.ogg',0,1,0,100)
		M.Stun(max(10/distance, 3))
		M.Weaken(max(10/distance, 3))
		M.setEarDamage(M.ear_damage + rand(0, 5), max(M.ear_deaf,15))
		if (M.ear_damage >= 15)
			M << "Your ears start to ring badly!"
			if(prob(M.ear_damage - 10 + 5))
				M << "You can't hear anything!"
				M.disabilities |= DEAF
		else
			if (M.ear_damage >= 5)
				M << "Your ears start to ring!"


code:
//improvised explosives//

/obj/item/weapon/grenade/iedcasing
	name = "improvised firebomb"
	desc = "A weak, improvised incendiary device."
	w_class = 2
	icon = 'icons/obj/grenade.dmi'
	icon_state = "improvised_grenade"
	item_state = "flashbang"
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	slot_flags = SLOT_BELT
	active = 0
	det_time = 50
	display_timer = 0
	var/range = 3
	var/times = list()

/obj/item/weapon/grenade/iedcasing/New(loc)
	..()
	overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
	overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired")
	times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
	det_time = text2num(pickweight(times))
	if(det_time < 0) //checking for 'duds'
		range = 1
		det_time = rand(30,80)
	else
		range = pick(2,2,2,3,3,3,4)

/obj/item/weapon/grenade/iedcasing/CheckParts()
	var/obj/item/weapon/reagent_containers/food/drinks/soda_cans/can = locate() in contents
	if(can)
		var/muh_layer = can.layer
		can.layer = FLOAT_LAYER
		underlays += can
		can.layer = muh_layer

/obj/item/weapon/grenade/iedcasing/attack_self(mob/user) //
	if(!active)
		if(clown_check(user))
			user << "You light the [name]!"
			active = 1
			overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
			icon_state = initial(icon_state) + "_active"
			add_fingerprint(user)
			var/turf/bombturf = get_turf(src)
			var/area/A = get_area(bombturf)

			message_admins("[key_name_admin(usr)]? (FLW) 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]).")
			if(iscarbon(user))
				var/mob/living/carbon/C = user
				C.throw_mode_on()
			spawn(det_time)
				prime()

/obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up
	update_mob()
	explosion(src.loc,-1,-1,2, flame_range = 4)	// small explosion, plus a very large fireball.
	qdel(src)

/obj/item/weapon/grenade/iedcasing/examine(mob/user)
	..()
	user << "You can't tell when it will explode!"


code:
/obj/item/weapon/grenade
	name = "grenade"
	desc = "It has an adjustable timer."
	w_class = 2
	icon = 'icons/obj/grenade.dmi'
	icon_state = "grenade"
	item_state = "flashbang"
	throw_speed = 3
	throw_range = 7
	flags = CONDUCT
	slot_flags = SLOT_BELT
	burn_state = FLAMMABLE
	burntime = 5
	var/active = 0
	var/det_time = 50
	var/display_timer = 1

/obj/item/weapon/grenade/burn()
	prime()
	..()

/obj/item/weapon/grenade/proc/clown_check(mob/living/carbon/human/user)
	if(user.disabilities & CLUMSY && prob(50))
		user << "Huh? How does this thing work?"
		active = 1
		icon_state = initial(icon_state) + "_active"
		playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
		spawn(5)
			if(user)
				user.drop_item()
			prime()
		return 0
	return 1

/*/obj/item/weapon/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
	if (istype(target, /obj/item/weapon/storage)) return ..() // Trying to put it in a full container
	if (istype(target, /obj/item/weapon/gun/grenadelauncher)) return ..()
	if((user.get_active_hand() == src) && (!active) && (clown_check(user)) && target.loc != src.loc)
		user << "You prime the [name]! [det_time/10] seconds!"
		active = 1
		icon_state = initial(icon_state) + "_active"
		playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
		spawn(det_time)
			prime()
			return
		user.dir = get_dir(user, target)
		user.drop_item()
		var/t = (isturf(target) ? target : target.loc)
		walk_towards(src, t, 3)
	return*/

/obj/item/weapon/grenade/examine(mob/user)
	..()
	if(display_timer)
		if(det_time > 1)
			user << "The timer is set to [det_time/10] second\s."
		else
			user << "\The [src] is set for instant detonation."

/obj/item/weapon/grenade/attack_self(mob/user)
	if(!active)
		if(clown_check(user))
			user << "You prime the [name]! [det_time/10] seconds!"
			playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
			active = 1
			icon_state = initial(icon_state) + "_active"
			add_fingerprint(user)
			var/turf/bombturf = get_turf(src)
			var/area/A = get_area(bombturf)
			message_admins("[key_name_admin(usr)]? (FLW) 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]).")
			if(iscarbon(user))
				var/mob/living/carbon/C = user
				C.throw_mode_on()
			spawn(det_time)
				prime()

/obj/item/weapon/grenade/proc/prime()

/obj/item/weapon/grenade/proc/update_mob()
	if(ismob(loc))
		var/mob/M = loc
		M.unEquip(src)

/obj/item/weapon/grenade/attackby(obj/item/weapon/W, mob/user, params)
	if(istype(W, /obj/item/weapon/screwdriver))
		switch(det_time)
			if ("1")
				det_time = 10
				user << "You set the [name] for 1 second detonation time."
			if ("10")
				det_time = 30
				user << "You set the [name] for 3 second detonation time."
			if ("30")
				det_time = 50
				user << "You set the [name] for 5 second detonation time."
			if ("50")
				det_time = 1
				user << "You set the [name] for instant detonation."
		add_fingerprint(user)
	..()

/obj/item/weapon/grenade/attack_hand()
	walk(src, null, null)
	..()

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

/obj/item/weapon/grenade/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
	if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
		owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!")
		prime()
		return 1 //It hit the grenade, not them


code:
/obj/item/weapon/grenade/smokebomb
	name = "smoke grenade"
	desc = "The word 'Dank' is scribbled on it in crayon."
	icon = 'icons/obj/grenade.dmi'
	icon_state = "smokewhite"
	det_time = 20
	item_state = "flashbang"
	slot_flags = SLOT_BELT
	var/datum/effect_system/smoke_spread/bad/smoke

/obj/item/weapon/grenade/smokebomb/New()
	..()
	src.smoke = new /datum/effect_system/smoke_spread/bad
	src.smoke.attach(src)

/obj/item/weapon/grenade/smokebomb/Destroy()
	qdel(smoke)
	return ..()

/obj/item/weapon/grenade/smokebomb/prime()
	update_mob()
	playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
	smoke.set_up(4, usr.loc)
	smoke.start()

	for(var/obj/effect/blob/B in view(8,src))
		var/damage = round(30/(get_dist(B,src)+1))
		B.health -= damage
		B.update_icon()
	sleep(80)
	qdel(src)


code:
/obj/item/weapon/grenade/spawnergrenade
	desc = "It will unleash unleash an unspecified anomaly into the vicinity."
	name = "delivery grenade"
	icon = 'icons/obj/grenade.dmi'
	icon_state = "delivery"
	item_state = "flashbang"
	origin_tech = "materials=3;magnets=4"
	var/spawner_type = null // must be an object path
	var/deliveryamt = 1 // amount of type to deliver

/obj/item/weapon/grenade/spawnergrenade/prime()			// Prime now just handles the two loops that query for people in lockers and people who can see it.
	update_mob()
	if(spawner_type && deliveryamt)
		// Make a quick flash
		var/turf/T = get_turf(src)
		playsound(T, 'sound/effects/phasein.ogg', 100, 1)
		for(var/mob/living/carbon/C in viewers(T, null))
			C.flash_eyes()

		for(var/i=1, i<=deliveryamt, i++)
			var/atom/movable/x = new spawner_type
			x.loc = T
			if(prob(50))
				for(var/j = 1, j <= rand(1, 3), j++)
					step(x, pick(NORTH,SOUTH,EAST,WEST))

			// Spawn some hostile syndicate critters

	qdel(src)

/obj/item/weapon/grenade/spawnergrenade/manhacks
	name = "viscerator delivery grenade"
	spawner_type = /mob/living/simple_animal/hostile/viscerator
	deliveryamt = 5
	origin_tech = "materials=3;magnets=4;syndicate=4"

/obj/item/weapon/grenade/spawnergrenade/spesscarp
	name = "carp delivery grenade"
	spawner_type = /mob/living/simple_animal/hostile/carp
	deliveryamt = 5
	origin_tech = "materials=3;magnets=4;syndicate=4"

/obj/item/weapon/grenade/spawnergrenade/syndiesoap
	name = "Mister Scrubby"
	spawner_type = /obj/item/weapon/soap/syndie


code:
/obj/item/weapon/grenade/syndieminibomb
	desc = "A syndicate manufactured explosive used to sow destruction and chaos"
	name = "syndicate minibomb"
	icon = 'icons/obj/grenade.dmi'
	icon_state = "syndicate"
	item_state = "flashbang"
	origin_tech = "materials=3;magnets=4;syndicate=4"

/obj/item/weapon/grenade/syndieminibomb/prime()
	update_mob()
	explosion(src.loc,1,2,4,flame_range = 2)
	qdel(src)

/obj/item/weapon/grenade/syndieminibomb/concussion
	name = "HE Grenade"
	desc = "A compact shrapnel grenade meant to devestate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
	icon_state = "concussion"
	origin_tech = "materials=3;magnets=4;syndicate=2"

/obj/item/weapon/grenade/syndieminibomb/concussion/prime()
	update_mob()
	explosion(src.loc,0,2,3,flame_range = 3)
	qdel(src)

/obj/item/weapon/grenade/syndieminibomb/concussion/frag
	name = "frag grenade"
	desc = "Fire in the hole."
	icon_state = "frag"

/obj/item/weapon/grenade/gluon
    desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
    name = "gluon grenade"
    icon = 'icons/obj/grenade.dmi'
    icon_state = "bluefrag"
    item_state = "flashbang"
    var/freeze_range = 4
    var/rad_damage = 35
    var/stamina_damage = 30

/obj/item/weapon/grenade/gluon/prime()
        update_mob()
        playsound(loc, 'sound/effects/EMPulse.ogg', 50, 1)
        radiation_pulse(loc,freeze_range,freeze_range+1,rad_damage)
        for(var/turf/T in view(freeze_range,loc))
                if(istype(T,/turf/open/floor))
                        var/turf/open/floor/F = T
                        F.wet = TURF_WET_ICE
                for(var/mob/living/carbon/L in T)
                        L.adjustStaminaLoss(stamina_damage)
                        L.bodytemperature -= 230
        qdel(src)


code:
/obj/item/weapon/restraints
	breakouttime = 600

//Handcuffs

/obj/item/weapon/restraints/handcuffs
	name = "handcuffs"
	desc = "Use this to keep prisoners in line."
	gender = PLURAL
	icon = 'icons/obj/items.dmi'
	icon_state = "handcuff"
	flags = CONDUCT
	slot_flags = SLOT_BELT
	throwforce = 0
	w_class = 2
	throw_speed = 3
	throw_range = 5
	materials = list(MAT_METAL=500)
	origin_tech = "materials=1"
	breakouttime = 600 //Deciseconds = 60s = 1 minute
	var/cuffsound = 'sound/weapons/handcuffs.ogg'
	var/trashtype = null //for disposable cuffs

/obj/item/weapon/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user)
	if(!istype(C))
		return
	if(user.disabilities & CLUMSY && prob(50))
		user << "Uh... how do those things work?!"
		apply_cuffs(user,user)
		return

	if(!C.handcuffed)
		C.visible_message("[user] is trying to put [src.name] on [C]!", \
							"[user] is trying to put [src.name] on [C]!")

		playsound(loc, cuffsound, 30, 1, -2)
		if(do_mob(user, C, 30))
			apply_cuffs(C,user)
			user << "You handcuff [C]."
			if(istype(src, /obj/item/weapon/restraints/handcuffs/cable))
				feedback_add_details("handcuffs","C")
			else
				feedback_add_details("handcuffs","H")

			add_logs(user, C, "handcuffed")
		else
			user << "You fail to handcuff [C]!"

/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0)
	if(target.handcuffed)
		return

	if(!user.drop_item() && !dispense)
		return

	var/obj/item/weapon/restraints/handcuffs/cuffs = src
	if(trashtype)
		cuffs = new trashtype()
	else if(dispense)
		cuffs = new type()

	cuffs.loc = target
	target.handcuffed = cuffs

	target.update_handcuffed()
	if(trashtype && !dispense)
		qdel(src)
	return

/obj/item/weapon/restraints/handcuffs/cable
	name = "cable restraints"
	desc = "Looks like some cables tied together. Could be used to tie something up."
	icon_state = "cuff_red"
	item_state = "coil_red"
	materials = list(MAT_METAL=150, MAT_GLASS=75)
	breakouttime = 300 //Deciseconds = 30s
	cuffsound = 'sound/weapons/cablecuff.ogg'
	var/datum/robot_energy_storage/wirestorage = null

/obj/item/weapon/restraints/handcuffs/cable/attack(mob/living/carbon/C, mob/living/carbon/human/user)
	if(!istype(C))
		return
	if(wirestorage && wirestorage.energy < 15)
		user << "You need at least 15 wire to restrain [C]!"
		return
	return ..()

/obj/item/weapon/restraints/handcuffs/cable/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0)
	if(wirestorage)
		if(!wirestorage.use_charge(15))
			user << "You need at least 15 wire to restrain [target]!"
			return
		return ..(target, user, 1)

	return ..()

/obj/item/weapon/restraints/handcuffs/cable/red
	icon_state = "cuff_red"

/obj/item/weapon/restraints/handcuffs/cable/yellow
	icon_state = "cuff_yellow"

/obj/item/weapon/restraints/handcuffs/cable/blue
	icon_state = "cuff_blue"
	item_state = "coil_blue"

/obj/item/weapon/restraints/handcuffs/cable/green
	icon_state = "cuff_green"

/obj/item/weapon/restraints/handcuffs/cable/pink
	icon_state = "cuff_pink"

/obj/item/weapon/restraints/handcuffs/cable/orange
	icon_state = "cuff_orange"

/obj/item/weapon/restraints/handcuffs/cable/cyan
	icon_state = "cuff_cyan"

/obj/item/weapon/restraints/handcuffs/cable/white
	icon_state = "cuff_white"

/obj/item/weapon/restraints/handcuffs/alien
	icon_state = "handcuffAlien"

/obj/item/weapon/restraints/handcuffs/fake
	name = "fake handcuffs"
	desc = "Fake handcuffs meant for gag purposes."
	breakouttime = 10 //Deciseconds = 1s

/obj/item/weapon/restraints/handcuffs/fake/kinky
	name = "kinky handcuffs"
	desc = "Fake handcuffs meant for erotic roleplay."
	icon_state = "handcuffGag"

/obj/item/weapon/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
	..()
	if(istype(I, /obj/item/stack/rods))
		var/obj/item/stack/rods/R = I
		if (R.use(1))
			var/obj/item/weapon/wirerod/W = new /obj/item/weapon/wirerod
			if(!remove_item_from_storage(user))
				user.unEquip(src)
			user.put_in_hands(W)
			user << "You wrap the cable restraint around the top of the rod."
			qdel(src)
		else
			user << "You need one rod to make a wired rod!"
			return
	else if(istype(I, /obj/item/stack/sheet/metal))
		var/obj/item/stack/sheet/metal/M = I
		if(M.amount < 6)
			user << "You need at least six metal sheets to make good enough weights!"
			return
		user << "You begin to apply [I] to [src]..."
		if(do_after(user, 35, target = src))
			var/obj/item/weapon/restraints/legcuffs/bola/S = new /obj/item/weapon/restraints/legcuffs/bola
			M.use(6)
			user.put_in_hands(S)
			user << "You make some weights out of [I] and tie them to [src]."
			if(!remove_item_from_storage(user))
				user.unEquip(src)
			qdel(src)

/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user)
	if(isrobot(user))
		if(!C.handcuffed)
			playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
			C.visible_message("[user] is trying to put zipties on [C]!", \
								"[user] is trying to put zipties on [C]!")
			if(do_mob(user, C, 30))
				if(!C.handcuffed)
					C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
					C.update_handcuffed()
					user << "You handcuff [C]."
					add_logs(user, C, "handcuffed")
			else
				user << "You fail to handcuff [C]!"

/obj/item/weapon/restraints/handcuffs/cable/zipties
	name = "zipties"
	desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
	icon_state = "cuff_white"
	materials = list()
	breakouttime = 450 //Deciseconds = 45s
	trashtype = /obj/item/weapon/restraints/handcuffs/cable/zipties/used

/obj/item/weapon/restraints/handcuffs/cable/zipties/used
	desc = "A pair of broken zipties."
	icon_state = "cuff_white_used"

/obj/item/weapon/restraints/handcuffs/cable/zipties/used/attack()
	return

//Legcuffs

/obj/item/weapon/restraints/legcuffs
	name = "leg cuffs"
	desc = "Use this to keep prisoners in line."
	gender = PLURAL
	icon = 'icons/obj/items.dmi'
	icon_state = "handcuff"
	flags = CONDUCT
	throwforce = 0
	w_class = 3
	origin_tech = "materials=1"
	slowdown = 7
	breakouttime = 300	//Deciseconds = 30s = 0.5 minute

/obj/item/weapon/restraints/legcuffs/beartrap
	name = "bear trap"
	throw_speed = 1
	throw_range = 1
	icon_state = "beartrap"
	desc = "A trap used to catch bears and other legged creatures."
	var/armed = 0
	var/trap_damage = 20

/obj/item/weapon/restraints/legcuffs/beartrap/New()
	..()
	icon_state = "[initial(icon_state)][armed]"

/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user)
	user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.")
	playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
	return (BRUTELOSS)

/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user)
	..()
	if(ishuman(user) && !user.stat && !user.restrained())
		armed = !armed
		icon_state = "[initial(icon_state)][armed]"
		user << "[src] is now [armed ? "armed" : "disarmed"]"

/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj)
	if(armed && isturf(src.loc))
		if(isliving(AM))
			var/mob/living/L = AM
			var/snap = 0
			var/def_zone = "chest"
			if(iscarbon(L))
				var/mob/living/carbon/C = L
				snap = 1
				if(!C.lying)
					def_zone = pick("l_leg", "r_leg")
					if(!C.legcuffed) //beartrap can't cuff your leg if there's already a beartrap or legcuffs.
						C.legcuffed = src
						src.loc = C
						C.update_inv_legcuffed()
						feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart.
			else if(isanimal(L))
				var/mob/living/simple_animal/SA = L
				if(!SA.flying && SA.mob_size > MOB_SIZE_TINY)
					snap = 1
			if(snap)
				armed = 0
				icon_state = "[initial(icon_state)][armed]"
				playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
				L.visible_message("[L] triggers \the [src].", \
						"You trigger \the [src]!")
				L.apply_damage(trap_damage,BRUTE, def_zone)
	..()

/obj/item/weapon/restraints/legcuffs/beartrap/energy
	name = "energy snare"
	armed = 1
	icon_state = "e_snare"
	trap_damage = 0

/obj/item/weapon/restraints/legcuffs/beartrap/energy/New()
	..()
	spawn(100)
		if(!istype(loc, /mob))
			var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
			sparks.set_up(1, 1, src)
			sparks.start()
			qdel(src)

/obj/item/weapon/restraints/legcuffs/beartrap/energy/dropped()
	..()
	qdel(src)

/obj/item/weapon/restraints/legcuffs/beartrap/energy/attack_hand(mob/user)
	Crossed(user) //honk

/obj/item/weapon/restraints/legcuffs/bola
	name = "bola"
	desc = "A restraining device designed to be thrown at the target. Upon connecting with said target, it will wrap around their legs, making it difficult for them to move quickly."
	icon_state = "bola"
	breakouttime = 35//easy to apply, easy to break out of
	gender = NEUTER
	var/weaken = 0

/obj/item/weapon/restraints/legcuffs/bola/throw_impact(atom/hit_atom)
	if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
		return//abort
	var/mob/living/carbon/C = hit_atom
	if(!C.legcuffed)
		visible_message("\The [src] ensnares [C]!")
		C.legcuffed = src
		src.loc = C
		C.update_inv_legcuffed()
		feedback_add_details("handcuffs","B")
		C << "\The [src] ensnares you!"
		C.Weaken(weaken)

/obj/item/weapon/restraints/legcuffs/bola/tactical//traitor variant
	name = "reinforced bola"
	desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody."
	icon_state = "bola_r"
	breakouttime = 70
	weaken = 1


code:
/obj/item/weapon/holosign_creator
	name = "holographic sign projector"
	desc = "A handy-dandy holographic projector that displays a janitorial sign."
	icon = 'icons/obj/device.dmi'
	icon_state = "signmaker"
	item_state = "electronic"
	force = 0
	w_class = 2
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	origin_tech = "programming=3"
	flags = NOBLUDGEON
	var/list/signs = list()
	var/max_signs = 10
	var/creation_time = 0 //time to create a holosign in deciseconds.
	var/holosign_type = /obj/effect/overlay/holograph/wetsign
	var/holocreator_busy = 0 //to prevent placing multiple holo barriers at once

/obj/item/weapon/holosign_creator/afterattack(atom/target, mob/user, flag)
	if(flag)
		if(!check_allowed_items(target, 1))
			return
		var/turf/T = get_turf(target)
		var/obj/effect/overlay/holograph/H = locate(holosign_type) in T
		if(H)
			user << "You use [src] to deactivate [H]."
			signs.Remove(H)
			qdel(H)
		else
			if(!is_blocked_turf(T)) //can't put holograms on a tile that has dense stuff
				if(holocreator_busy)
					user << "[src] is busy creating a hologram."
					return
				if(signs.len < max_signs)
					playsound(src.loc, 'sound/machines/click.ogg', 20, 1)
					if(creation_time)
						holocreator_busy = 1
						if(!do_after(user, creation_time, target = target))
							holocreator_busy = 0
							return
						holocreator_busy = 0
						if(signs.len >= max_signs)
							return
						if(is_blocked_turf(T)) //don't try to sneak dense stuff on our tile during the wait.
							return
					H = new holosign_type(get_turf(target))
					signs += H
					user << "You create \a [H] with [src]."
				else
					user << "[src] is projecting at max capacity!"

/obj/item/weapon/holosign_creator/attack(mob/living/carbon/human/M, mob/user)
	return

/obj/item/weapon/holosign_creator/attack_self(mob/user)
	if(signs.len)
		var/list/L = signs.Copy()
		for(var/sign in L)
			qdel(sign)
			signs -= sign
		user << "You clear all active holograms."

/obj/item/weapon/holosign_creator/security
	name = "security holobarrier projector"
	desc = "A holographic projector that creates holographic security barriers."
	icon_state = "signmaker_sec"
	holosign_type = /obj/effect/overlay/holograph/barrier
	creation_time = 30
	max_signs = 6

/obj/item/weapon/holosign_creator/engineering
	name = "engineering holobarrier projector"
	desc = "A holographic projector that creates holographic engineering barriers."
	icon_state = "signmaker_engi"
	holosign_type = /obj/effect/overlay/holograph/barrier/engineering
	creation_time = 30
	max_signs = 6

/obj/effect/overlay/holograph
	icon = 'icons/effects/effects.dmi'
	anchored = 1
	var/holo_integrity = 1

/obj/effect/overlay/holograph/attackby(obj/item/weapon/W, mob/user, params)
	if(!W.force || (W.flags & (ABSTRACT|NOBLUDGEON)))
		return
	if(W.force >= 10)
		take_damage(3, user)
	else
		take_damage(1, user)

/obj/effect/overlay/holograph/blob_act()
	qdel(src)

/obj/effect/overlay/holograph/attack_animal(mob/living/simple_animal/M)
	take_damage(5, M)

/obj/effect/overlay/holograph/attack_alien(mob/living/carbon/alien/A)
	take_damage(5, A)

/obj/effect/overlay/holograph/attack_hand(mob/living/user)
	take_damage(1, user)

/obj/effect/overlay/holograph/mech_melee_attack(obj/mecha/M)
	playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
	visible_message("[M.name] has hit [src].")
	qdel(src)

/obj/effect/overlay/holograph/attack_slime(mob/living/simple_animal/slime/S)
	if(S.is_adult)
		take_damage(5, S)
	else
		take_damage(2, S)

/obj/effect/overlay/holograph/proc/take_damage(amount, mob/living/user)
	user.changeNext_move(CLICK_CD_MELEE)
	user.do_attack_animation(src)
	playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
	user.visible_message("[user] hits [src].", \
						 "You hit [src]." )
	holo_integrity -= amount
	if(holo_integrity <= 0)
		qdel(src)

/obj/effect/overlay/holograph/hitby(atom/movable/AM)
	..()
	var/tforce = 1
	if(ismob(AM))
		tforce = 5
	else if(isobj(AM))
		var/obj/item/I = AM
		tforce = max(1, I.throwforce * 0.2)
	playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
	holo_integrity -= tforce
	if(holo_integrity <= 0)
		qdel(src)

/obj/effect/overlay/holograph/bullet_act(obj/item/projectile/P)
	if((P.damage_type == BRUTE || P.damage_type == BURN))
		holo_integrity -= P.damage * 0.5
		if(holo_integrity <= 0)
			qdel(src)

/obj/effect/overlay/holograph/wetsign
	name = "wet floor sign"
	desc = "The words flicker as if they mean nothing."
	icon_state = "holosign"

/obj/effect/overlay/holograph/barrier
	name = "holo barrier"
	desc = "A short holographic barrier which can only be passed by walking."
	icon_state = "holosign_sec"
	pass_flags = LETPASSTHROW
	density = 1
	holo_integrity = 4

/obj/effect/overlay/holograph/barrier/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
	if(!density)
		return 1
	if(air_group || (height==0))
		return 1
	if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE))
		return 1
	if(iscarbon(mover))
		var/mob/living/carbon/C = mover
		if(C.m_intent == "walk")
			return 1

/obj/effect/overlay/holograph/barrier/engineering
	icon_state = "holosign_engi"