code:
/obj/machinery/porta_turret
	name = "turret"
	icon = 'icons/obj/turrets.dmi'
	icon_state = "grey_target_prism"
	anchored = 1
	layer = 3
	invisibility = INVISIBILITY_OBSERVER	//the turret is invisible if it's inside its cover
	density = 1
	use_power = 1				//this turret uses and requires power
	idle_power_usage = 50		//when inactive, this turret takes up constant 50 Equipment power
	active_power_usage = 300	//when active, this turret takes up constant 300 Equipment power
	req_access = list(access_security)
	power_channel = EQUIP	//drains power from the EQUIPMENT channel

	var/base_icon_state = "grey"
	var/active_state = "Taser" // "Taser"/"Laser/"Bullet" ,blue/red/no glow on active turret
	var/off_state = "Off"

	var/emp_vunerable = 1 // Can be empd

	var/scan_range = 7
	var/atom/base = null //for turrets inside other objects

	var/lasercolor = ""		//Something to do with lasertag turrets, blame Sieve for not adding a comment.
	var/raised = 0			//if the turret cover is "open" and the turret is raised
	var/raising= 0			//if the turret is currently opening or closing its cover
	var/health = 80			//the turret's health
	var/locked = 1			//if the turret's behaviour control access is locked
	var/controllock = 0		//if the turret responds to control panels

	var/installation = /obj/item/weapon/gun/energy/gun/turret		//the type of weapon installed
	var/gun_charge = 0		//the charge of the gun inserted
	var/projectile = null	//holder for bullettype
	var/eprojectile = null	//holder for the shot when emagged
	var/reqpower = 500		//holder for power needed
	var/egun = null			//holder to handle certain guns switching bullettypes
	var/always_up = 0		//Will stay active
	var/has_cover = 1		//Hides the cover

	var/obj/machinery/porta_turret_cover/cover = null	//the cover that is covering this turret
	var/last_fired = 0		//world.time the turret last fired
	var/shot_delay = 15		//ticks until next shot (1.5 ?)

	var/check_records = 1	//checks if it can use the security records
	var/criminals = 1		//checks if it can shoot people on arrest
	var/auth_weapons = 0	//checks if it can shoot people that have a weapon they aren't authorized to have
	var/stun_all = 0		//if this is active, the turret shoots everything that isn't security or head of staff
	var/check_anomalies = 1	//checks if it can shoot at unidentified lifeforms (ie xenos)

	var/attacked = 0		//if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)

	var/on = 1				//determines if the turret is on
	var/disabled = 0

	var/shot_sound 			//what sound should play when the turret fires
	var/eshot_sound			//what sound should play when the emagged turret fires

	var/faction = "neutral"

	var/datum/effect_system/spark_spread/spark_system	//the spark system, used for generating... sparks?

/obj/machinery/porta_turret/New()
	..()
	if(!base)
		base = src
	icon_state = "[base_icon_state][off_state]"
	//Sets up a spark system
	spark_system = new /datum/effect_system/spark_spread
	spark_system.set_up(5, 0, src)
	spark_system.attach(src)

	if(has_cover)
		cover = new /obj/machinery/porta_turret_cover(loc)
		cover.parent_turret = src
	setup()
	if(!has_cover)
		popUp()

/obj/machinery/porta_turret/proc/get_base_icon()
	if(installation)
		switch(installation)
			if(/obj/item/weapon/gun/energy/laser/bluetag)
				return "blue"
			if(/obj/item/weapon/gun/energy/laser/redtag)
				return "red"
	return "grey"

/obj/machinery/porta_turret/proc/setup()

	var/obj/item/weapon/gun/energy/E= new installation	//All energy-based weapons are applicable
	var/obj/item/ammo_casing/shottype = E.ammo_type[1]

	projectile = shottype.projectile_type
	eprojectile = projectile
	shot_sound = shottype.fire_sound
	eshot_sound = shot_sound

	switch(E.type)
		if(/obj/item/weapon/gun/energy/laser/bluetag)
			eprojectile = /obj/item/projectile/beam/lasertag/bluetag
			lasercolor = "b"
			req_access = list(access_maint_tunnels, access_theatre)
			check_records = 0
			criminals = 0
			auth_weapons = 1
			stun_all = 0
			check_anomalies = 0
			shot_delay = 30

		if(/obj/item/weapon/gun/energy/laser/redtag)
			eprojectile = /obj/item/projectile/beam/lasertag/redtag
			lasercolor = "r"
			req_access = list(access_maint_tunnels, access_theatre)
			check_records = 0
			criminals = 0
			auth_weapons = 1
			stun_all = 0
			check_anomalies = 0
			shot_delay = 30
			active_state = "Laser"

		if(/obj/item/weapon/gun/energy/laser/practice)
			active_state = "Laser"
			eprojectile = /obj/item/projectile/beam

		if(/obj/item/weapon/gun/energy/laser/retro)
			active_state = "Laser"

		if(/obj/item/weapon/gun/energy/laser/captain)
			active_state = "Laser"

		if(/obj/item/weapon/gun/energy/lasercannon)
			active_state = "Laser"

		if(/obj/item/weapon/gun/energy/gun/advtaser)
			eprojectile = /obj/item/projectile/beam
			eshot_sound = 'sound/weapons/Laser.ogg'

		if(/obj/item/weapon/gun/energy/gun)
			eprojectile = /obj/item/projectile/beam	//If it has, going to kill mode
			eshot_sound = 'sound/weapons/Laser.ogg'
			egun = 1

		if(/obj/item/weapon/gun/energy/gun/nuclear)
			eprojectile = /obj/item/projectile/beam	//If it has, going to kill mode
			eshot_sound = 'sound/weapons/Laser.ogg'
			egun = 1

		if(/obj/item/weapon/gun/energy/gun/turret)
			eprojectile = /obj/item/projectile/beam	//If it has, going to copypaste mode
			eshot_sound = 'sound/weapons/Laser.ogg'
			egun = 1

	base_icon_state = get_base_icon()

/obj/machinery/porta_turret/Destroy()
	//deletes its own cover with it
	qdel(cover)
	cover = null
	return ..()

/obj/machinery/porta_turret/attack_ai(mob/user)
	return attack_hand(user)

/obj/machinery/porta_turret/attack_hand(mob/user)
	. = ..()
	if(.)
		return
	var/dat

	//The browse() text, similar to ED-209s and beepskies.
	if(!lasercolor)	//Lasertag turrets have less options
		dat += text({"
					<TT>Automatic Portable Turret Installation</TT>

					Status: []

					Behaviour controls are [locked ? "locked" : "unlocked"]"},

					"[on ? "On" : "Off"]" )

		if(!locked)
			dat += text({"

						Check for Weapon Authorization: []

						Check Security Records: []

						Neutralize Identified Criminals: []

						Neutralize All Non-Security and Non-Command Personnel: []

						Neutralize All Unidentified Life Signs: []
"},

						"[auth_weapons ? "Yes" : "No"]",
						"[check_records ? "Yes" : "No"]",
						"[criminals ? "Yes" : "No"]",
						"[stun_all ? "Yes" : "No"]",
						"[check_anomalies ? "Yes" : "No"]" )
	else
		if(istype(user,/mob/living/carbon/human))
			var/mob/living/carbon/human/H = user
			if(lasercolor == "b" && istype(H.wear_suit, /obj/item/clothing/suit/redtag))
				return
			if(lasercolor == "r" && istype(H.wear_suit, /obj/item/clothing/suit/bluetag))
				return
		dat += text({"
					<TT>Automatic Portable Turret Installation</TT>

					Status: []
"},

					"[on ? "On" : "Off"]" )

	user << browse("<TITLE>Automatic Portable Turret Installation</TITLE>[dat]", "window=autosec")
	onclose(user, "autosec")
	return

/obj/machinery/porta_turret/Topic(href, href_list)
	if(..())
		return
	usr.set_machine(src)
	add_fingerprint(usr)
	if(href_list["power"] && !locked)
		if(anchored)	//you can't turn a turret on/off if it's not anchored/secured
			on = !on	//toggle on/off
		else
			usr << "It has to be secured first!"

		updateUsrDialog()
		return

	switch(href_list["operation"])	//toggles customizable behavioural protocols
		if("authweapon")
			auth_weapons = !auth_weapons
		if("checkrecords")
			check_records = !check_records
		if("shootcrooks")
			criminals = !criminals
		if("shootall")
			stun_all = !stun_all
		if("checkxenos")
			check_anomalies = !check_anomalies
	updateUsrDialog()

/obj/machinery/porta_turret/power_change()

	if(!anchored)
		icon_state = "turretCover"
		return
	if(stat & BROKEN)
		icon_state = "[base_icon_state]Broken"
	else
		if( powered() )
			if(on)
				icon_state = "[base_icon_state][active_state]"
			else
				icon_state = "[base_icon_state][off_state]"
			stat &= ~NOPOWER
		else
			spawn(rand(0, 15))
				icon_state = "[base_icon_state][off_state]"
				stat |= NOPOWER

/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, params)
	if(stat & BROKEN)
		if(istype(I, /obj/item/weapon/crowbar))
			//If the turret is destroyed, you can remove it with a crowbar to
			//try and salvage its components
			user << "You begin prying the metal coverings off..."
			if(do_after(user, 20/I.toolspeed, target = src))
				if(prob(70))
					user << "You remove the turret and salvage some components."
					if(installation)
						var/obj/item/weapon/gun/energy/Gun = new installation(loc)
						Gun.power_supply.charge = gun_charge
						Gun.update_icon()
						lasercolor = null
					if(prob(50))
						new /obj/item/stack/sheet/metal(loc, rand(1,4))
					if(prob(50))
						new /obj/item/device/assembly/prox_sensor(loc)
				else
					user << "You remove the turret but did not manage to salvage anything."
				qdel(src)

	else if((istype(I, /obj/item/weapon/wrench)) && (!on))
		if(raised) return
		//This code handles moving the turret around. After all, it's a portable turret!
		if(!anchored && !isinspace())
			anchored = 1
			invisibility = INVISIBILITY_OBSERVER
			icon_state = "[base_icon_state][off_state]"
			user << "You secure the exterior bolts on the turret."
			if(has_cover)
				cover = new /obj/machinery/porta_turret_cover(loc) //create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second
				cover.parent_turret = src //make the cover's parent src
		else if(anchored)
			anchored = 0
			user << "You unsecure the exterior bolts on the turret."
			icon_state = "turretCover"
			invisibility = 0
			qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover.

	else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
		//Behavior lock/unlock mangement
		if(allowed(user))
			locked = !locked
			user << "Controls are now [locked ? "locked" : "unlocked"]."
		else
			user << "Access denied."
	else if(istype(I,/obj/item/device/multitool) && !locked)
		var/obj/item/device/multitool/M = I
		M.buffer = src
		user << "You add [src] to multitool buffer."
	else
		//if the turret was attacked with the intention of harming it:
		user.changeNext_move(CLICK_CD_MELEE)
		take_damage(I.force * 0.5)
		if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off
			if(!attacked && !emagged)
				attacked = 1
				spawn()
					sleep(60)
					attacked = 0
		..()

/obj/machinery/porta_turret/attack_animal(mob/living/simple_animal/M)
	M.changeNext_move(CLICK_CD_MELEE)
	M.do_attack_animation(src)
	if(M.melee_damage_upper == 0 || (M.melee_damage_type != BRUTE && M.melee_damage_type != BURN))
		return
	if(!(stat & BROKEN))
		visible_message("[M] [M.attacktext] [src]!")
		add_logs(M, src, "attacked")
		take_damage(M.melee_damage_upper)
	else
		M << "That object is useless to you."
	return

/obj/machinery/porta_turret/attack_alien(mob/living/carbon/alien/humanoid/M)
	M.changeNext_move(CLICK_CD_MELEE)
	M.do_attack_animation(src)
	if(!(stat & BROKEN))
		playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
		visible_message("[M] has slashed at [src]!")
		add_logs(M, src, "attacked")
		take_damage(15)
	else
		M << "\green That object is useless to you."
	return

/obj/machinery/porta_turret/emag_act(mob/user)
	if(!emagged)
		user << "You short out [src]'s threat assessment circuits."
		visible_message("[src] hums oddly...")
		emagged = 1
		active_state = "Laser"
		controllock = 1
		on = 0 //turns off the turret temporarily
		sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
		on = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here

/obj/machinery/porta_turret/bullet_act(obj/item/projectile/Proj)
	if(on)
		if(!attacked && !emagged)
			attacked = 1
			spawn()
				sleep(60)
				attacked = 0

	var/damage_dealt = 0
	if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
		damage_dealt = Proj.damage

	..()

	if(damage_dealt)
		if(prob(45))
			spark_system.start()
		take_damage(damage_dealt)

	if(lasercolor == "b" && disabled == 0)
		if(istype(Proj, /obj/item/projectile/beam/lasertag/redtag))
			disabled = 1
			qdel(Proj)
			sleep(100)
			disabled = 0
	if(lasercolor == "r" && disabled == 0)
		if(istype(Proj, /obj/item/projectile/beam/lasertag/bluetag))
			disabled = 1
			qdel(Proj)
			sleep(100)
			disabled = 0

/obj/machinery/porta_turret/emp_act(severity)
	if(on && emp_vunerable)
		//if the turret is on, the EMP no matter how severe disables the turret for a while
		//and scrambles its settings, with a slight chance of having an emag effect
		check_records = pick(0, 1)
		criminals = pick(0, 1)
		auth_weapons = pick(0, 1)
		stun_all = pick(0, 0, 0, 0, 1)	//stun_all is a pretty big deal, so it's least likely to get turned on

		on=0
		spawn(rand(60,600))
			if(!on)
				on=1

	..()

/obj/machinery/porta_turret/ex_act(severity, target)
	if(severity >= 3)	//turret dies if an explosion touches it!
		die()
	else
		qdel(src)

/obj/machinery/porta_turret/proc/take_damage(damage)
	health -= damage
	if(health <= 0)
		die()

/obj/machinery/porta_turret/proc/die()	//called when the turret dies, ie, health <= 0
	health = 0
	density = 0
	stat |= BROKEN	//enables the BROKEN bit
	icon_state = "[base_icon_state]Broken"
	invisibility = 0
	spark_system.start()	//creates some sparks because they look cool
	density = 1
	qdel(cover)	//deletes the cover - no need on keeping it there!

/obj/machinery/porta_turret/process()
	//the main machinery process

	set background = BACKGROUND_ENABLED

	if(cover == null && anchored)	//if it has no cover and is anchored
		if(stat & BROKEN)	//if the turret is borked
			qdel(cover)	//delete its cover, assuming it has one. Workaround for a pesky little bug
		else
			if(has_cover)
				cover = new /obj/machinery/porta_turret_cover(loc)	//if the turret has no cover and is anchored, give it a cover
				cover.parent_turret = src	//assign the cover its parent_turret, which would be this (src)

	if(stat & (NOPOWER|BROKEN))
		if(!always_up)
			//if the turret has no power or is broken, make the turret pop down if it hasn't already
			popDown()
		return

	if(!on)
		if(!always_up)
			//if the turret is off, make it pop down
			popDown()
		return

	var/list/targets = calculate_targets()

	if(!tryToShootAt(targets))
		if(!always_up)
			popDown() // no valid targets, close the cover

/obj/machinery/porta_turret/proc/calculate_targets()
	var/list/targets = list()
	var/turretview = view(scan_range, base)
	for(var/A in turretview)
		if(check_anomalies)//if it's set to check for simple animals
			if(istype(A, /mob/living/simple_animal))
				var/mob/living/simple_animal/SA = A
				if(SA.stat || in_faction(SA)) //don't target if dead or in faction
					continue
				targets += SA

		if(istype(A, /mob/living/carbon))
			var/mob/living/carbon/C = A
			//If not emagged, only target non downed carbons
			if(!emagged && (C.stat || C.handcuffed || C.lying))
				continue

			//If emagged, target all but dead carbons
			if(emagged && C.stat == DEAD)
				continue

			//if the target is a human and not in our faction, analyze threat level
			if(istype(C, /mob/living/carbon/human) && !in_faction(C))
				if(assess_perp(C) >= 4)
					targets += C

			else if(check_anomalies) //non humans who are not simple animals (xenos etc)
				if(!in_faction(C))
					targets += C

		if(istype(A, /obj/mecha/))
			var/obj/mecha/M = A
			//If there is a user and they're not in our faction
			if(M.occupant && !in_faction(M.occupant))
				if(assess_perp(M.occupant) >= 4)
					targets += M

	return targets

/obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets)
	while(targets.len > 0)
		var/atom/movable/M = pick(targets)
		targets -= M
		if(target(M))
			return 1

/obj/machinery/porta_turret/proc/popUp()	//pops the turret up
	if(disabled)
		return
	if(raising || raised)
		return
	if(stat & BROKEN)
		return
	invisibility = 0
	raising = 1
	if(cover)
		flick("popup", cover)
	sleep(10)
	raising = 0
	if(cover)
		cover.icon_state = "openTurretCover"
	raised = 1
	layer = 4

/obj/machinery/porta_turret/proc/popDown()	//pops the turret down
	if(disabled)
		return
	if(raising || !raised)
		return
	if(stat & BROKEN)
		return
	layer = 3
	raising = 1
	if(cover)
		flick("popdown", cover)
	sleep(10)
	raising = 0
	if(cover)
		cover.icon_state = "turretCover"
	raised = 0
	invisibility = 2
	icon_state = "[base_icon_state][off_state]"

/obj/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp)
	var/threatcount = 0	//the integer returned

	if(emagged)
		return 10	//if emagged, always return 10.

	if((stun_all || attacked) && !allowed(perp))
		//if the turret has been attacked or is angry, target all non-sec people
		if(!allowed(perp))
			return 10

	if(auth_weapons)	//check for weapon authorization
		if(isnull(perp.wear_id) || istype(perp.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))

			if(allowed(perp) && !lasercolor) //if the perp has security access, return 0
				return 0

			if((istype(perp.l_hand, /obj/item/weapon/gun) && !istype(perp.l_hand, /obj/item/weapon/gun/projectile/revolver/doublebarrel)) || istype(perp.l_hand, /obj/item/weapon/melee/baton))
				threatcount += 4

			if((istype(perp.r_hand, /obj/item/weapon/gun) && !istype(perp.r_hand, /obj/item/weapon/gun/projectile/revolver/doublebarrel)) || istype(perp.r_hand, /obj/item/weapon/melee/baton))
				threatcount += 4

			if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee/baton))
				threatcount += 2

	if(lasercolor == "b")	//Lasertag turrets target the opposing team, how great is that? -Sieve
		threatcount = 0		//But does not target anyone else
		if(istype(perp.wear_suit, /obj/item/clothing/suit/redtag))
			threatcount += 4
		if(istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/redtag) || istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/redtag))
			threatcount += 4
		if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/redtag))
			threatcount += 2

	if(lasercolor == "r")
		threatcount = 0
		if(istype(perp.wear_suit, /obj/item/clothing/suit/bluetag))
			threatcount += 4
		if((istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
			threatcount += 4
		if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/bluetag))
			threatcount += 2

	if(check_records)	//if the turret can check the records, check if they are set to *Arrest* on records
		var/perpname = perp.get_face_name(perp.get_id_name())
		var/datum/data/record/R = find_record("name", perpname, data_core.security)
		if(!R || (R.fields["criminal"] == "*Arrest*"))
			threatcount += 4

	return threatcount

/obj/machinery/porta_turret/proc/in_faction(mob/target)
	if(!(faction in target.faction))
		return 0
	return 1

/obj/machinery/porta_turret/proc/target(atom/movable/target)
	if(disabled)
		return
	if(target)
		spawn()
			popUp()				//pop the turret up if it's not already up.
		dir = get_dir(base, target)	//even if you can't shoot, follow the target
		spawn()
			shootAt(target)
		return 1
	return

/obj/machinery/porta_turret/proc/shootAt(atom/movable/target)
	if(!raised) //the turret has to be raised in order to fire - makes sense, right?
		return

	if(!emagged)	//if it hasn't been emagged, cooldown before shooting again
		if(last_fired + shot_delay > world.time)
			return
		last_fired = world.time

	var/turf/T = get_turf(src)
	var/turf/U = get_turf(target)
	if(!istype(T) || !istype(U))
		return

	icon_state = "[base_icon_state][active_state]"
	var/obj/item/projectile/A
	//any emagged turrets drains 2x power and uses a different projectile?
	if(!emagged)
		use_power(reqpower)
		A = new projectile(T)
		playsound(loc, shot_sound, 75, 1)
	else
		use_power(reqpower * 2)
		A = new eprojectile(T)
		playsound(loc, eshot_sound, 75, 1)

	//Shooting Code:
	A.original = target
	A.current = T
	A.yo = U.y - T.y
	A.xo = U.x - T.x
	A.fire()
	return A

/obj/machinery/porta_turret/proc/setState(on, emagged)
	if(controllock)
		return
	src.on = on
	src.emagged = emagged
	if(emagged)
		src.active_state = "Laser"
	src.power_change()

/obj/machinery/porta_turret/stationary
	emagged = 1

/obj/machinery/porta_turret/stationary/New()
		installation = new/obj/item/weapon/gun/energy/laser(loc)
		..()

/obj/machinery/porta_turret/syndicate
	installation = null
	always_up = 1
	use_power = 0
	has_cover = 0
	scan_range = 9
	projectile = /obj/item/projectile/bullet
	eprojectile = /obj/item/projectile/bullet
	shot_sound = 'sound/weapons/Gunshot.ogg'
	eshot_sound = 'sound/weapons/Gunshot.ogg'
	base_icon_state = "syndie"
	active_state = "Bullet"
	faction = "syndicate"
	emp_vunerable = 0

/obj/machinery/porta_turret/syndicate/setup()
	return

/obj/machinery/porta_turret/syndicate/assess_perp(mob/living/carbon/human/perp)
	return 10 //Syndicate turrets shoot everything not in their faction

/obj/machinery/porta_turret/syndicate/pod
	health = 40
	projectile = /obj/item/projectile/bullet/weakbullet3
	eprojectile = /obj/item/projectile/bullet/weakbullet3

/obj/machinery/porta_turret/ai
	faction = "silicon"

/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
	return 10 //AI turrets shoot at everything not in their faction

////////////////////////
//Turret Control Panel//
////////////////////////

/obj/machinery/turretid
	name = "turret control panel"
	desc = "Used to control a room's automated defenses."
	icon = 'icons/obj/machines/turret_control.dmi'
	icon_state = "control_standby"
	anchored = 1
	density = 0
	var/enabled = 1
	var/lethal = 0
	var/locked = 1
	var/control_area = null //can be area name, path or nothing.
	var/ailock = 0 // AI cannot use this
	req_access = list(access_ai_upload)
	var/list/obj/machinery/porta_turret/turrets = list()

/obj/machinery/turretid/New(loc, ndir = 0, built = 0)
	..()
	if(built)
		dir = ndir
		locked = 0
		pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
		pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
	power_change() //Checks power and initial settings
	return

/obj/machinery/turretid/initialize() //map-placed turrets autolink turrets
	if(control_area && istext(control_area))
		for(var/area/A in world)
			if(A.name == control_area)
				control_area = A
				break

	if(!control_area)
		var/area/CA = get_area(src)
		if(CA.master && CA.master != CA)
			control_area = CA.master
		else
			control_area = CA

	for(var/obj/machinery/porta_turret/T in get_area_all_atoms(control_area))
		turrets |= T

/obj/machinery/turretid/attackby(obj/item/I, mob/user, params)
	if(stat & BROKEN) return

	if (istype(I,/obj/item/device/multitool))
		var/obj/item/device/multitool/M = I
		if(M.buffer && istype(M.buffer,/obj/machinery/porta_turret))
			turrets |= M.buffer
			user << "You link \the [M.buffer] with \the [src]"
			return

	if (istype(user, /mob/living/silicon))
		return src.attack_hand(user)

	if( get_dist(src, user) == 0 )		// trying to unlock the interface
		if (src.allowed(usr))
			if(emagged)
				user << "The turret control is unresponsive."
				return

			locked = !locked
			user << "You [ locked ? "lock" : "unlock"] the panel."
			if (locked)
				if (user.machine==src)
					user.unset_machine()
					user << browse(null, "window=turretid")
			else
				if (user.machine==src)
					src.attack_hand(user)
		else
			user << "Access denied."

/obj/machinery/turretid/emag_act(mob/user)
	if(!emagged)
		user << "You short out the turret controls' access analysis module."
		emagged = 1
		locked = 0
		if(user && user.machine==src)
			src.attack_hand(user)

/obj/machinery/turretid/attack_ai(mob/user)
	if(!ailock || IsAdminGhost(user))
		return attack_hand(user)
	else
		user << "There seems to be a firewall preventing you from accessing this device."

/obj/machinery/turretid/attack_hand(mob/user as mob)
	if ( get_dist(src, user) > 0 )
		if ( !(issilicon(user) || IsAdminGhost(user)) )
			user << "You are too far away."
			user.unset_machine()
			user << browse(null, "window=turretid")
			return

	user.set_machine(src)
	var/loc = src.loc
	if (istype(loc, /turf))
		loc = loc:loc
	if (!istype(loc, /area))
		user << text("Turret badly positioned - loc.loc is [].", loc)
		return
	var/area/area = loc
	var/t = ""

	if(src.locked && (!(istype(user, /mob/living/silicon) || IsAdminGhost(user))))
		t += "
Swipe ID card to unlock interface
"
	else
		if (!istype(user, /mob/living/silicon) && !IsAdminGhost(user))
			t += "
Swipe ID card to lock interface
"
		t += text("Turrets [] - []?
\n", src.enabled?"activated":"deactivated", src, src.enabled?"Disable":"Enable")
		t += text("Currently set for [] - Change to []?
\n", src.lethal?"lethal":"stun repeatedly", src,  src.lethal?"Stun repeatedly":"Lethal")

	//user << browse(t, "window=turretid")
	//onclose(user, "turretid")
	var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([area.name])")
	popup.set_content(t)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()

/obj/machinery/turretid/Topic(href, href_list)
	if(..())
		return
	if (src.locked)
		if (!(istype(usr, /mob/living/silicon) || IsAdminGhost(usr)))
			usr << "Control panel is locked!"
			return
	if (href_list["toggleOn"])
		toggle_on()
	else if (href_list["toggleLethal"])
		toggle_lethal()
	src.attack_hand(usr)

/obj/machinery/turretid/proc/toggle_lethal()
	lethal = !lethal
	updateTurrets()

/obj/machinery/turretid/proc/toggle_on()
	enabled = !enabled
	updateTurrets()

/obj/machinery/turretid/proc/updateTurrets()
	for (var/obj/machinery/porta_turret/aTurret in turrets)
		aTurret.setState(enabled, lethal)
	src.update_icon()

/obj/machinery/turretid/power_change()
	..()
	update_icon()

/obj/machinery/turretid/update_icon()
	..()
	if(stat & NOPOWER)
		icon_state = "control_off"
	else if (enabled)
		if (lethal)
			icon_state = "control_kill"
		else
			icon_state = "control_stun"
	else
		icon_state = "control_standby"

/obj/item/wallframe/turret_control
	name = "turret control frame"
	desc = "Used for building turret control panels"
	icon = 'icons/obj/apc_repair.dmi'
	icon_state = "apc_frame"
	result_path = /obj/machinery/turretid
	materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)


code:
#define PTURRET_UNSECURED  0
#define PTURRET_BOLTED  1
#define PTURRET_START_INTERNAL_ARMOUR  2
#define PTURRET_INTERNAL_ARMOUR_ON  3
#define PTURRET_GUN_EQUIPPED  4
#define PTURRET_SENSORS_ON  5
#define PTURRET_CLOSED  6
#define PTURRET_START_EXTERNAL_ARMOUR  7
#define PTURRET_EXTERNAL_ARMOUR_ON  8
/obj/machinery/porta_turret_construct
	name = "turret frame"
	icon = 'icons/obj/turrets.dmi'
	icon_state = "turret_frame"
	density = 1
	var/build_step = PTURRET_UNSECURED //the current step in the building process
	var/finish_name = "turret"	//the name applied to the product turret
	var/installation = null		//the gun type installed
	var/gun_charge = 0			//the gun charge of the gun type installed

/obj/machinery/porta_turret_construct/attackby(obj/item/I, mob/user, params)
	//this is a bit unwieldy but self-explanatory
	switch(build_step)
		if(PTURRET_UNSECURED)	//first step
			if(istype(I, /obj/item/weapon/wrench) && !anchored)
				playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
				user << "You secure the external bolts."
				anchored = 1
				build_step = PTURRET_BOLTED
				return

			else if(istype(I, /obj/item/weapon/crowbar) && !anchored)
				playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
				user << "You dismantle the turret construction."
				new /obj/item/stack/sheet/metal( loc, 5)
				qdel(src)
				return

		if(PTURRET_BOLTED)
			if(istype(I, /obj/item/stack/sheet/metal))
				var/obj/item/stack/sheet/metal/M = I
				if(M.use(2))
					user << "You add some metal armor to the interior frame."
					build_step = PTURRET_START_INTERNAL_ARMOUR
					icon_state = "turret_frame2"
				else
					user << "You need two sheets of metal to continue construction!"
				return

			else if(istype(I, /obj/item/weapon/wrench))
				playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
				user << "You unfasten the external bolts."
				anchored = 0
				build_step = PTURRET_UNSECURED
				return

		if(PTURRET_START_INTERNAL_ARMOUR)
			if(istype(I, /obj/item/weapon/wrench))
				playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
				user << "You bolt the metal armor into place."
				build_step = PTURRET_INTERNAL_ARMOUR_ON
				return

			else if(istype(I, /obj/item/weapon/weldingtool))
				var/obj/item/weapon/weldingtool/WT = I
				if(!WT.isOn())
					return
				if(WT.get_fuel() < 5) //uses up 5 fuel.
					user << "You need more fuel to complete this task!"
					return

				playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1)
				user << "You start to remove the turret's interior metal armor..."
				if(do_after(user, 20/I.toolspeed, target = src))
					if(!WT.isOn() || !WT.remove_fuel(5, user))
						return
					build_step = PTURRET_BOLTED
					user << "You remove the turret's interior metal armor."
					new /obj/item/stack/sheet/metal( loc, 2)
					return

		if(PTURRET_INTERNAL_ARMOUR_ON)
			if(istype(I, /obj/item/weapon/gun/energy)) //the gun installation part
				var/obj/item/weapon/gun/energy/E = I
				if(!user.drop_item())
					return
				installation = I.type
				gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge
				user << "You add [I] to the turret."
				build_step = PTURRET_GUN_EQUIPPED
				qdel(I)
				return

			else if(istype(I, /obj/item/weapon/wrench))
				playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
				user << "You remove the turret's metal armor bolts."
				build_step = PTURRET_START_INTERNAL_ARMOUR
				return

		if(PTURRET_GUN_EQUIPPED)
			if(isprox(I))
				build_step = PTURRET_SENSORS_ON
				if(!user.drop_item())
					return
				user << "You add the proximity sensor to the turret."
				qdel(I)
				return

		if(PTURRET_SENSORS_ON)
			if(istype(I, /obj/item/weapon/screwdriver))
				playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
				build_step = PTURRET_CLOSED
				user << "You close the internal access hatch."
				return

		if(PTURRET_CLOSED)
			if(istype(I, /obj/item/stack/sheet/metal))
				var/obj/item/stack/sheet/metal/M = I
				if(M.use(2))
					user << "You add some metal armor to the exterior frame."
					build_step = PTURRET_START_EXTERNAL_ARMOUR
				else
					user << "You need two sheets of metal to continue construction!"
				return

			else if(istype(I, /obj/item/weapon/screwdriver))
				playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
				build_step = PTURRET_SENSORS_ON
				user << "You open the internal access hatch."
				return

		if(PTURRET_START_EXTERNAL_ARMOUR)
			if(istype(I, /obj/item/weapon/weldingtool))
				var/obj/item/weapon/weldingtool/WT = I
				if(!WT.isOn())
					return
				if(WT.get_fuel() < 5)
					user << "You need more fuel to complete this task!"

				playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1)
				user << "You begin to weld the turret's armor down..."
				if(do_after(user, 30/I.toolspeed, target = src))
					if(!WT.isOn() || !WT.remove_fuel(5, user))
						return
					build_step = PTURRET_EXTERNAL_ARMOUR_ON
					user << "You weld the turret's armor down."

					//The final step: create a full turret
					var/obj/machinery/porta_turret/turret = new/obj/machinery/porta_turret(loc)
					turret.name = finish_name
					turret.installation = installation
					turret.gun_charge = gun_charge
					turret.setup()

					qdel(src)

			else if(istype(I, /obj/item/weapon/crowbar))
				playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
				user << "You pry off the turret's exterior armor."
				new /obj/item/stack/sheet/metal(loc, 2)
				build_step = PTURRET_CLOSED
				return

	if(istype(I, /obj/item/weapon/pen))	//you can rename turrets like bots!
		var/t = stripped_input(user, "Enter new turret name", name, finish_name)
		if(!t)
			return
		if(!Adjacent(user))
			return

		finish_name = t
		return
	..()

/obj/machinery/porta_turret_construct/attack_hand(mob/user)
	switch(build_step)
		if(PTURRET_GUN_EQUIPPED)
			build_step = PTURRET_INTERNAL_ARMOUR_ON

			var/obj/item/weapon/gun/energy/Gun = new installation(loc)
			Gun.power_supply.charge = gun_charge
			Gun.update_icon()
			installation = null
			gun_charge = 0
			user << "You remove [Gun] from the turret frame."

		if(PTURRET_SENSORS_ON)
			user << "You remove the prox sensor from the turret frame."
			new /obj/item/device/assembly/prox_sensor(loc)
			build_step = PTURRET_GUN_EQUIPPED

/obj/machinery/porta_turret_construct/attack_ai()
	return

license: mit


code:
/************************
* PORTABLE TURRET COVER *
************************/

/obj/machinery/porta_turret_cover
	name = "turret"
	icon = 'icons/obj/turrets.dmi'
	icon_state = "turretCover"
	anchored = 1
	layer = 3.5
	density = 0
	var/obj/machinery/porta_turret/parent_turret = null

//The below code is pretty much just recoded from the initial turret object. It's necessary but uncommented because it's exactly the same!
//>necessary
//I'm not fixing it because i'm fucking bored of this code already, but someone should just reroute these to the parent turret's procs.

/obj/machinery/porta_turret_cover/attack_ai(mob/user)
	. = ..()
	if(.)
		return

	return parent_turret.attack_ai(user)

/obj/machinery/porta_turret_cover/attack_hand(mob/user)
	. = ..()
	if(.)
		return

	return parent_turret.attack_hand(user)

/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/weapon/wrench) && !parent_turret.on)
		if(parent_turret.raised)
			return

		if(!parent_turret.anchored)
			parent_turret.anchored = 1
			parent_turret.invisibility = INVISIBILITY_OBSERVER
			parent_turret.icon_state = "grey_target_prism"
			user << "You secure the exterior bolts on the turret."
		else
			parent_turret.anchored = 0
			user << "You unsecure the exterior bolts on the turret."
			parent_turret.icon_state = "turretCover"
			parent_turret.invisibility = 0
			qdel(src)

	else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
		if(parent_turret.allowed(user))
			parent_turret.locked = !parent_turret.locked
			user << "Controls are now [parent_turret.locked ? "locked" : "unlocked"]."
			updateUsrDialog()
		else
			user << "Access denied."
	else if(istype(I,/obj/item/device/multitool) && !parent_turret.locked)
		var/obj/item/device/multitool/M = I
		M.buffer = parent_turret
		user << "You add [parent_turret] to multitool buffer."
	else
		user.changeNext_move(CLICK_CD_MELEE)
		parent_turret.health -= I.force * 0.5
		if(parent_turret.health <= 0)
			parent_turret.die()
		if(I.force * 0.5 > 2)
			if(!parent_turret.attacked && !parent_turret.emagged)
				parent_turret.attacked = 1
				spawn()
					sleep(30)
					parent_turret.attacked = 0
		..()

/obj/machinery/porta_turret_cover/can_be_overridden()
	. = 0

/obj/machinery/porta_turret_cover/emag_act(mob/user)
	if(!parent_turret.emagged)
		user << "You short out [parent_turret]'s threat assessment circuits."
		visible_message("[parent_turret] hums oddly...")
		parent_turret.emagged = 1
		parent_turret.on = 0
		sleep(40)
		parent_turret.on = 1


code:
/obj/machinery/recharger
	name = "recharger"
	icon = 'icons/obj/stationobjs.dmi'
	icon_state = "recharger0"
	desc = "A charging dock for energy based weaponry."
	anchored = 1
	use_power = 1
	idle_power_usage = 4
	active_power_usage = 250
	var/obj/item/weapon/charging = null
	var/recharge_coeff = 1

/obj/machinery/recharger/New()
	..()
	component_parts = list()
	component_parts += new /obj/item/weapon/circuitboard/recharger()
	component_parts += new /obj/item/weapon/stock_parts/capacitor()
	RefreshParts()

/obj/machinery/recharger/RefreshParts()
	for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
		recharge_coeff = C.rating

/obj/machinery/recharger/attackby(obj/item/weapon/G, mob/user, params)
	if(istype(G, /obj/item/weapon/wrench))
		if(charging)
			user << "Remove the charging item first!"
			return
		anchored = !anchored
		power_change()
		user << "You [anchored ? "attached" : "detached"] [src]."
		playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
		return
	if(istype(user,/mob/living/silicon))
		return
	if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton) || istype(G, /obj/item/ammo_box/magazine/recharge))
		if(anchored)
			if(charging || panel_open)
				return

			//Checks to make sure he's not in space doing it, and that the area got proper power.
			var/area/a = get_area(src)
			if(!isarea(a) || a.power_equip == 0)
				user << "[src] blinks red as you try to insert [G]."
				return

			if (istype(G, /obj/item/weapon/gun/energy))
				var/obj/item/weapon/gun/energy/gun = G
				if(!gun.can_charge)
					user << "Your gun has no external power connector."
					return
			if(!user.drop_item())
				return

			G.loc = src
			charging = G
			use_power = 2
			update_icon()
		else
			user << "[src] isn't connected to anything!"

	if (anchored && !charging)
		if(default_deconstruction_screwdriver(user, "rechargeropen", "recharger0", G))
			return

		if(panel_open && istype(G, /obj/item/weapon/crowbar))
			default_deconstruction_crowbar(G)
			return

		if(exchange_parts(user, G))
			return

/obj/machinery/recharger/attack_hand(mob/user)
	if(issilicon(user))
		return

	add_fingerprint(user)
	if(charging)
		charging.update_icon()
		charging.loc = loc
		user.put_in_hands(charging)
		charging = null
		use_power = 1
		update_icon()

/obj/machinery/recharger/attack_paw(mob/user)
	return attack_hand(user)

/obj/machinery/recharger/attack_tk(mob/user)
	if(charging)
		charging.update_icon()
		charging.loc = loc
		charging = null
		use_power = 1
		update_icon()

/obj/machinery/recharger/process()
	if(stat & (NOPOWER|BROKEN) || !anchored)
		return

	var/using_power = 0
	if(charging)
		if(istype(charging, /obj/item/weapon/gun/energy))
			var/obj/item/weapon/gun/energy/E = charging
			if(E.power_supply.charge < E.power_supply.maxcharge)
				E.power_supply.give(E.power_supply.chargerate * recharge_coeff)
				use_power(250 * recharge_coeff)
				using_power = 1

		if(istype(charging, /obj/item/weapon/melee/baton))
			var/obj/item/weapon/melee/baton/B = charging
			if(B.bcell)
				if(B.bcell.give(B.bcell.chargerate * recharge_coeff))
					use_power(200 * recharge_coeff)
					using_power = 1

		if(istype(charging, /obj/item/ammo_box/magazine/recharge))
			var/obj/item/ammo_box/magazine/recharge/R = charging
			if(R.stored_ammo.len < R.max_ammo)
				R.stored_ammo += new R.ammo_type(R)
				use_power(200 * recharge_coeff)
				using_power = 1

	update_icon(using_power)

/obj/machinery/recharger/power_change()
	..()
	update_icon()

/obj/machinery/recharger/emp_act(severity)
	if(stat & (NOPOWER|BROKEN) || !anchored)
		..(severity)
		return

	if(istype(charging,  /obj/item/weapon/gun/energy))
		var/obj/item/weapon/gun/energy/E = charging
		if(E.power_supply)
			E.power_supply.emp_act(severity)

	else if(istype(charging, /obj/item/weapon/melee/baton))
		var/obj/item/weapon/melee/baton/B = charging
		if(B.bcell)
			B.bcell.charge = 0
	..(severity)

/obj/machinery/recharger/update_icon(using_power = 0)	//we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
	if(stat & (NOPOWER|BROKEN) || !anchored)
		icon_state = "rechargeroff"
		return
	if(panel_open)
		icon_state = "rechargeropen"
		return
	if(charging)
		if(using_power)
			icon_state = "recharger1"
		else
			icon_state = "recharger2"
		return
	icon_state = "recharger0"


code:
/obj/machinery/recharge_station
	name = "cyborg recharging station"
	icon = 'icons/obj/objects.dmi'
	icon_state = "borgcharger0"
	density = 0
	anchored = 1
	use_power = 1
	idle_power_usage = 5
	active_power_usage = 1000
	var/circuitboard = "/obj/item/weapon/circuitboard/cyborgrecharger"
	req_access = list(access_robotics)
	var/recharge_speed
	var/repairs
	state_open = 1

/obj/machinery/recharge_station/New()
	..()
	component_parts = list()
	component_parts += new /obj/item/weapon/circuitboard/cyborgrecharger(null)
	component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
	component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
	component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
	component_parts += new /obj/item/weapon/stock_parts/cell/high(null)
	RefreshParts()
	update_icon()

/obj/machinery/recharge_station/RefreshParts()
	recharge_speed = 0
	repairs = 0
	for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
		recharge_speed += C.rating * 100
	for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
		repairs += M.rating - 1
	for(var/obj/item/weapon/stock_parts/cell/C in component_parts)
		recharge_speed *= C.maxcharge / 10000

/obj/machinery/recharge_station/process()
	if(!is_operational())
		return

	if(occupant)
		process_occupant()
	return 1

/obj/machinery/recharge_station/relaymove(mob/user)
	if(user.stat)
		return
	open_machine()

/obj/machinery/recharge_station/emp_act(severity)
	if(stat & (BROKEN|NOPOWER))
		..(severity)
		return
	if(occupant)
		occupant.emp_act(severity)
	open_machine()
	..(severity)

/obj/machinery/recharge_station/ex_act(severity, target)
	if(occupant)
		open_machine()
	..()

/obj/machinery/recharge_station/attack_paw(mob/user)
	return attack_hand(user)

/obj/machinery/recharge_station/attack_ai(mob/user)
	return attack_hand(user)

/obj/machinery/recharge_station/attackby(obj/item/P, mob/user, params)
	if(state_open)
		if(default_deconstruction_screwdriver(user, "borgdecon2", "borgcharger0", P))
			return

	if(exchange_parts(user, P))
		return

	if(default_pry_open(P))
		return

	default_deconstruction_crowbar(P)

/obj/machinery/recharge_station/attack_hand(mob/user)
	if(..(user,1,set_machine = 0))
		return

	toggle_open()
	add_fingerprint(user)

/obj/machinery/recharge_station/proc/toggle_open()
	if(state_open)
		close_machine()
	else
		open_machine()

/obj/machinery/recharge_station/open_machine()
	..()
	use_power = 1

/obj/machinery/recharge_station/close_machine()
	if(!panel_open)
		for(var/mob/living/silicon/robot/R in loc)
			R.forceMove(src)
			occupant = R
			use_power = 2
			add_fingerprint(R)
			break
		state_open = 0
		density = 1
		update_icon()

/obj/machinery/recharge_station/update_icon()
	if(is_operational())
		if(state_open)
			icon_state = "borgcharger0"
		else
			icon_state = (occupant ? "borgcharger1" : "borgcharger2")
	else
		icon_state = (state_open ? "borgcharger-u0" : "borgcharger-u1")

/obj/machinery/recharge_station/power_change()
	..()
	update_icon()

/obj/machinery/recharge_station/proc/process_occupant()
	if(occupant)
		var/mob/living/silicon/robot/R = occupant
		restock_modules()
		if(repairs)
			R.heal_organ_damage(repairs, repairs - 1)
		if(R.cell)
			R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)

/obj/machinery/recharge_station/proc/restock_modules()
	if(occupant)
		var/mob/living/silicon/robot/R = occupant
		if(R && R.module)
			var/coeff = recharge_speed * 0.005
			R.module.respawn_consumable(R, coeff)


code:
var/const/SAFETY_COOLDOWN = 100

/obj/machinery/recycler
	name = "recycler"
	desc = "A large crushing machine which is used to recycle small items ineffeciently; there are lights on the side of it."
	icon = 'icons/obj/recycling.dmi'
	icon_state = "grinder-o0"
	layer = MOB_LAYER+1 // Overhead
	anchored = 1
	density = 1
	var/safety_mode = 0 // Temporality stops the machine if it detects a mob
	var/grinding = 0
	var/icon_name = "grinder-o"
	var/blood = 0
	var/eat_dir = WEST
	var/amount_produced = 1
	var/datum/material_container/materials

/obj/machinery/recycler/New()
	// On us
	..()
	component_parts = list()
	component_parts += new /obj/item/weapon/circuitboard/recycler(null)
	component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
	component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
	materials = new /datum/material_container(src, list(MAT_METAL=1, MAT_GLASS=1, MAT_PLASMA=1, MAT_SILVER=1, MAT_GOLD=1, MAT_DIAMOND=1, MAT_URANIUM=1, MAT_BANANIUM=1))
	RefreshParts()
	update_icon()

/obj/machinery/recycler/RefreshParts()
	var/amt_made = 0
	var/mat_mod = 0
	for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts)
		mat_mod = 2 * B.rating
	mat_mod *= 50000
	for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
		amt_made = 25 * M.rating //% of materials salvaged
	materials.max_amount = mat_mod
	amount_produced = min(100, amt_made)

/obj/machinery/recycler/examine(mob/user)
	..()
	user << "The power light is [(stat & NOPOWER) ? "off" : "on"]."
	user << "The safety-mode light is [safety_mode ? "on" : "off"]."
	user << "The safety-sensors status light is [emagged ? "off" : "on"]."

/obj/machinery/recycler/power_change()
	..()
	update_icon()

/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
	if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
		return

	if(exchange_parts(user, I))
		return

	if(default_pry_open(I))
		return

	if(default_unfasten_wrench(user, I))
		return

	default_deconstruction_crowbar(I)
	..()
	add_fingerprint(user)
	return

/obj/machinery/recycler/emag_act(mob/user)
	if(!emagged)
		emagged = 1
		if(safety_mode)
			safety_mode = 0
			update_icon()
		playsound(src.loc, "sparks", 75, 1, -1)
		user << "You use the cryptographic sequencer on the [src.name]."

/obj/machinery/recycler/update_icon()
	..()
	var/is_powered = !(stat & (BROKEN|NOPOWER))
	if(safety_mode)
		is_powered = 0
	icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end

// This is purely for admin possession !FUN!.
/obj/machinery/recycler/Bump(atom/movable/AM)
	..()
	if(AM)
		Bumped(AM)

/obj/machinery/recycler/Bumped(atom/movable/AM)

	if(stat & (BROKEN|NOPOWER))
		return
	if(!anchored)
		return
	if(safety_mode)
		return

	var/move_dir = get_dir(loc, AM.loc)
	if(move_dir == eat_dir)
		if(isliving(AM))
			if(emagged)
				eat(AM)
			else
				stop(AM)
		else if(istype(AM, /obj/item))
			recycle(AM)
		else // Can't recycle
			playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
			AM.loc = src.loc

/obj/machinery/recycler/proc/recycle(obj/item/I, sound = 1)
	I.loc = src.loc
	if(!istype(I))
		return

	if(sound)
		playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
	var/material_amount = materials.get_item_material_amount(I)
	if(!material_amount)
		qdel(I)
		return
	materials.insert_item(I, multiplier = (amount_produced / 100))
	qdel(I)
	materials.retrieve_all()

/obj/machinery/recycler/proc/stop(mob/living/L)
	playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
	safety_mode = 1
	update_icon()
	L.loc = src.loc

	spawn(SAFETY_COOLDOWN)
		playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
		safety_mode = 0
		update_icon()

/obj/machinery/recycler/proc/eat(mob/living/L)

	L.loc = src.loc

	if(issilicon(L))
		playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
	else
		playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)

	var/gib = 1
	// By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
	if(iscarbon(L))
		gib = 0
		if(L.stat == CONSCIOUS)
			L.say("ARRRRRRRRRRRGH!!!")
		add_blood(L)

	if(!blood && !issilicon(L))
		blood = 1
		update_icon()

	// Remove and recycle the equipped items.
	for(var/obj/item/I in L.get_equipped_items())
		if(L.unEquip(I))
			recycle(I, 0)

	// Instantly lie down, also go unconscious from the pain, before you die.
	L.Paralyse(5)

	// For admin fun, var edit emagged to 2.
	if(gib || emagged == 2)
		L.gib()
	else if(emagged == 1)
		L.adjustBruteLoss(1000)

/obj/item/weapon/paper/recycler
	name = "paper - 'garbage duty instructions'"
	info = "
New Assignment
 You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"


code:
/******************** Requests Console ********************/
/** Originally written by errorage, updated by: Carn, needs more work though. I just added some security fixes */

var/req_console_assistance = list()
var/req_console_supplies = list()
var/req_console_information = list()
var/list/obj/machinery/requests_console/allConsoles = list()

/obj/machinery/requests_console
	name = "requests console"
	desc = "A console intended to send requests to different departments on the station."
	anchored = 1
	icon = 'icons/obj/terminals.dmi'
	icon_state = "req_comp0"
	var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department
	var/list/messages = list() //List of all messages
	var/departmentType = 0
		// 0 = none (not listed, can only replied to)
		// 1 = assistance
		// 2 = supplies
		// 3 = info
		// 4 = ass + sup //Erro goddamn you just HAD to shorten "assistance" down to "ass"
		// 5 = ass + info
		// 6 = sup + info
		// 7 = ass + sup + info
	var/newmessagepriority = 0
		// 0 = no new message
		// 1 = normal priority
		// 2 = high priority
		// 3 = extreme priority - not implemented, will probably require some hacking... everything needs to have a hidden feature in this game.
	var/screen = 0
		// 0 = main menu,
		// 1 = req. assistance,
		// 2 = req. supplies
		// 3 = relay information
		// 4 = write msg - not used
		// 5 = choose priority - not used
		// 6 = sent successfully
		// 7 = sent unsuccessfully
		// 8 = view messages
		// 9 = authentication before sending
		// 10 = send announcement
	var/silent = 0 // set to 1 for it not to beep all the time
	var/hackState = 0
		// 0 = not hacked
		// 1 = hacked
	var/announcementConsole = 0
		// 0 = This console cannot be used to send department announcements
		// 1 = This console can send department announcements
	var/open = 0 // 1 if open
	var/announceAuth = 0 //Will be set to 1 when you authenticate yourself for announcements
	var/msgVerified = "" //Will contain the name of the person who verified it
	var/msgStamped = "" //If a message is stamped, this will contain the stamp name
	var/message = "";
	var/dpt = ""; //the department which will be receiving the message
	var/priority = -1 ; //Priority of the message being sent
	var/obj/item/device/radio/Radio
	var/emergency //If an emergency has been called by this device. Acts as both a cooldown and lets the responder know where it the emergency was triggered from
	luminosity = 0

/obj/machinery/requests_console/power_change()
	..()
	update_icon()

/obj/machinery/requests_console/update_icon()
	if(open)
		if(hackState == 0)
			icon_state="req_comp_open"
		else
			icon_state="req_comp_rewired"
	else if(stat & NOPOWER)
		if(icon_state != "req_comp_off")
			icon_state = "req_comp_off"
	else
		if(emergency || (newmessagepriority == 3))
			icon_state = "req_comp3"
		else if(newmessagepriority == 2)
			icon_state = "req_comp2"
		else if(newmessagepriority == 1)
			icon_state = "req_comp1"
		else
			icon_state = "req_comp0"

/obj/machinery/requests_console/New()
	name = "\improper [department] requests console"
	allConsoles += src
	//req_console_departments += department
	switch(departmentType)
		if(1)
			if(!("[department]" in req_console_assistance))
				req_console_assistance += department
		if(2)
			if(!("[department]" in req_console_supplies))
				req_console_supplies += department
		if(3)
			if(!("[department]" in req_console_information))
				req_console_information += department
		if(4)
			if(!("[department]" in req_console_assistance))
				req_console_assistance += department
			if(!("[department]" in req_console_supplies))
				req_console_supplies += department
		if(5)
			if(!("[department]" in req_console_assistance))
				req_console_assistance += department
			if(!("[department]" in req_console_information))
				req_console_information += department
		if(6)
			if(!("[department]" in req_console_supplies))
				req_console_supplies += department
			if(!("[department]" in req_console_information))
				req_console_information += department
		if(7)
			if(!("[department]" in req_console_assistance))
				req_console_assistance += department
			if(!("[department]" in req_console_supplies))
				req_console_supplies += department
			if(!("[department]" in req_console_information))
				req_console_information += department

	Radio = new /obj/item/device/radio(src)
	Radio.listening = 0

/obj/machinery/requests_console/attack_hand(mob/user)
	if(..())
		return
	var/dat = ""
	if(!open)
		switch(screen)
			if(1)	//req. assistance
				dat += "Which department do you need assistance from?

"
				dat += "
"
				for(var/dpt in req_console_assistance)
					if (dpt != department)
						dat += "
"
						dat += "[dpt]	"
						dat += "Normal High"
						if (hackState == 1)
							dat += "EXTREME"
						dat += "	"
						dat += "
"
				dat += "
"
				dat += "
<< Back
"

			if(2)	//req. supplies
				dat += "Which department do you need supplies from?

"
				dat += "
"
				for(var/dpt in req_console_supplies)
					if (dpt != department)
						dat += "
"
						dat += "[dpt]	"
						dat += "Normal High"
						if (hackState == 1)
							dat += "EXTREME"
						dat += "	"
						dat += "
"
				dat += "
"
				dat += "
<< Back
"

			if(3)	//relay information
				dat += "Which department would you like to send information to?

"
				dat += "
"
				for(var/dpt in req_console_information)
					if (dpt != department)
						dat += "
"
						dat += "[dpt]	"
						dat += "Normal High"
						if (hackState == 1)
							dat += "EXTREME"
						dat += "	"
						dat += "
"
				dat += "
"
				dat += "
<< Back
"

			if(6)	//sent successfully
				dat += "Message sent.

"
				dat += "Continue
"

			if(7)	//unsuccessful; not sent
				dat += "An error occurred.

"
				dat += "Continue
"

			if(8)	//view messages
				for (var/obj/machinery/requests_console/Console in allConsoles)
					if (Console.department == department)
						Console.newmessagepriority = 0
						Console.update_icon()
						Console.SetLuminosity(1)
				newmessagepriority = 0
				update_icon()
				var/messageComposite = ""
				for(var/msg in messages) // This puts more recent messages at the *top*, where they belong.
					messageComposite = "
[msg]
" + messageComposite
				dat += messageComposite
				dat += "
<< Back to Main Menu
"

			if(9)	//authentication before sending
				dat += "Message Authentication

"
				dat += "Message for [dpt]: [message]

"
				dat += "
You may authenticate your message now by scanning your ID or your stamp

"
				dat += "Validated by: [msgVerified ? msgVerified : "Not Validated"]
"
				dat += "Stamped by: [msgStamped ? msgStamped : "Not Stamped"]

"
				dat += "Send Message
"
				dat += "
<< Discard Message
"

			if(10)	//send announcement
				dat += "
Station-wide Announcement
"
				if(announceAuth)
					dat += "
Authentication accepted

"
				else
					dat += "
Swipe your card to authenticate yourself

"
				dat += "Message: [message ? message : "No Message"]
"
				dat += "[message ? "Edit" : "Write"] Message

"
				if ((announceAuth || IsAdminGhost(user)) && message)
					dat += "Announce Message
"
				else
					dat += "Announce Message
"
				dat += "
<< Back
"

			else	//main menu
				screen = 0
				announceAuth = 0
				if (newmessagepriority == 1)
					dat += "
There are new messages

"
				if (newmessagepriority == 2)
					dat += "
There are new PRIORITY messages

"
				if (newmessagepriority == 3)
					dat += "
There are new EXTREME PRIORITY messages

"
				dat += "View Messages

"

				dat += "Request Assistance
"
				dat += "Request Supplies
"
				dat += "Relay Anonymous Information

"

				if(!emergency)
					dat += "Emergency: Security
"
					dat += "Emergency: Engineering
"
					dat += "Emergency: Medical

"
				else
					dat += "[emergency] has been dispatched to this location.

"

				if(announcementConsole)
					dat += "Send Station-wide Announcement

"
				if (silent)
					dat += "Speaker OFF"
				else
					dat += "Speaker ON"

		//user << browse("[dat]", "window=request_console")
		//onclose(user, "req_console")
		var/datum/browser/popup = new(user, "req_console", "[department] Requests Console", 450, 440)
		popup.set_content(dat)
		popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
		popup.open()
	return

/obj/machinery/requests_console/Topic(href, href_list)
	if(..())
		return
	usr.set_machine(src)
	add_fingerprint(usr)

	if(reject_bad_text(href_list["write"]))
		dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name

		var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
		if(new_message)
			message = new_message
			screen = 9
			if (text2num(href_list["priority"]) < 2)
				priority = -1
			else
				priority = text2num(href_list["priority"])
		else
			dpt = "";
			msgVerified = ""
			msgStamped = ""
			screen = 0
			priority = -1

	if(href_list["writeAnnouncement"])
		var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
		if(new_message)
			message = new_message
			if (text2num(href_list["priority"]) < 2)
				priority = -1
			else
				priority = text2num(href_list["priority"])
		else
			message = ""
			announceAuth = 0
			screen = 0

	if(href_list["sendAnnouncement"])
		if(!announcementConsole)
			return
		minor_announce(message, "[department] Announcement:")
		news_network.SubmitArticle(message, department, "Station Announcements", null)
		log_say("[key_name(usr)] has made a station announcement: [message]")
		message_admins("[key_name_admin(usr)] has made a station announcement.")
		announceAuth = 0
		message = ""
		screen = 0

	if(href_list["emergency"])
		if(!emergency)
			var/radio_freq
			switch(text2num(href_list["emergency"]))
				if(1) //Security
					radio_freq = SEC_FREQ
					emergency = "Security"
				if(2) //Engineering
					radio_freq = ENG_FREQ
					emergency = "Engineering"
				if(3) //Medical
					radio_freq = MED_FREQ
					emergency = "Medical"
			if(radio_freq)
				Radio.set_frequency(radio_freq)
				Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq)
				update_icon()
				spawn(3000)
					emergency = null
					update_icon()

	if( href_list["department"] && message )
		var/log_msg = message
		var/sending = message
		sending += "
"
		if (msgVerified)
			sending += msgVerified
			sending += "
"
		if (msgStamped)
			sending += msgStamped
			sending += "
"
		screen = 7 //if it's successful, this will get overrwritten (7 = unsufccessfull, 6 = successfull)
		if (sending)
			var/pass = 0
			for (var/obj/machinery/message_server/MS in machines)
				if(!MS.active) continue
				MS.send_rc_message(href_list["department"],department,log_msg,msgStamped,msgVerified,priority)
				pass = 1

			if(pass)
				var/radio_freq = 0
				switch(href_list["department"])
					if("bridge")
						radio_freq = COMM_FREQ
					if("medbay")
						radio_freq = MED_FREQ
					if("science")
						radio_freq = SCI_FREQ
					if("engineering")
						radio_freq = ENG_FREQ
					if("security")
						radio_freq = SEC_FREQ
					if("cargobay" || "mining")
						radio_freq = SUPP_FREQ
				Radio.set_frequency(radio_freq)
				var/authentic
				if(msgVerified || msgStamped)
					authentic = " (Authenticated)"

				var/alert = ""
				for (var/obj/machinery/requests_console/Console in allConsoles)
					if (ckey(Console.department) == ckey(href_list["department"]))
						switch(priority)
							if(2)		//High priority
								alert = "PRIORITY Alert in [department][authentic]"
								Console.createmessage(src, alert, sending, 2, 1)
							if(3)		// Extreme Priority
								alert = "EXTREME PRIORITY Alert from [department][authentic]"
								Console.createmessage(src, alert , sending, 3, 1)
							else		// Normal priority
								alert = "Message from [department][authentic]"
								Console.createmessage(src, alert , sending, 1, 1)
						screen = 6
						Console.SetLuminosity(2)

				if(radio_freq)
					Radio.talk_into(src,"[alert]: [message]",radio_freq)

				switch(priority)
					if(2)
						messages += "High Priority
To: [dpt]
[sending]"
					else
						messages += "To: [dpt]
[sending]"
			else
				say("NOTICE: No server detected!")

	//Handle screen switching
	switch(text2num(href_list["setScreen"]))
		if(null)	//skip
		if(1)		//req. assistance
			screen = 1
		if(2)		//req. supplies
			screen = 2
		if(3)		//relay information
			screen = 3
//		if(4)		//write message
//			screen = 4
		if(5)		//choose priority
			screen = 5
		if(6)		//sent successfully
			screen = 6
		if(7)		//unsuccessfull; not sent
			screen = 7
		if(8)		//view messages
			screen = 8
		if(9)		//authentication
			screen = 9
		if(10)		//send announcement
			if(!announcementConsole)
				return
			screen = 10
		else		//main menu
			dpt = ""
			msgVerified = ""
			msgStamped = ""
			message = ""
			priority = -1
			screen = 0

	//Handle silencing the console
	switch( href_list["setSilent"] )
		if(null)	//skip
		if("1")
			silent = 1
		else
			silent = 0

	updateUsrDialog()
	return

/obj/machinery/say_quote(input, list/spans)
	var/ending = copytext(input, length(input) - 2)
	if (ending == "!!!")
		return "blares, \"[attach_spans(input, spans)]\""

	return ..()

/obj/machinery/requests_console/proc/createmessage(source, title, message, priority)
	var/linkedsender
	if(istype(source, /obj/machinery/requests_console))
		var/obj/machinery/requests_console/sender = source
		linkedsender = "[sender.department]"
	else
		capitalize(source)
		linkedsender = source
	capitalize(title)
	switch(priority)
		if(2)		//High priority
			if(src.newmessagepriority < 2)
				src.newmessagepriority = 2
				src.update_icon()
			if(!src.silent)
				playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
				say(title)
				src.messages += "High Priority
From: [linkedsender]
[message]"

		if(3)		// Extreme Priority
			if(src.newmessagepriority < 3)
				src.newmessagepriority = 3
				src.update_icon()
			if(1)
				playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
				say(title)
			src.messages += "!!!Extreme Priority!!!
From: [linkedsender]
[message]"

		else		// Normal priority
			if(src.newmessagepriority < 1)
				src.newmessagepriority = 1
				src.update_icon()
			if(!src.silent)
				playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
				say(title)
			src.messages += "From: [linkedsender]
[message]"
	SetLuminosity(2)

/obj/machinery/requests_console/attackby(obj/item/weapon/O, mob/user, params)
	if (istype(O, /obj/item/weapon/crowbar))
		if(open)
			user << "You close the maintenance panel."
			open = 0
			icon_state="req_comp0"
		else
			user << "You open the maintenance panel."
			open = 1
			if(hackState == 0)
				icon_state="req_comp_open"
			else if(hackState == 1)
				icon_state="req_comp_rewired"
	if (istype(O, /obj/item/weapon/screwdriver))
		if(open)
			if(hackState == 0)
				user << "You modify the wiring."
				hackState = 1
				icon_state="req_comp_rewired"
			else if(hackState == 1)
				user << "You reset the wiring."
				hackState = 0
				icon_state="req_comp_open"
		else
			user << "You can't do much with that!"
	update_icon()

	var/obj/item/weapon/card/id/ID = O.GetID()
	if (ID)
		if(screen == 9)
			msgVerified = "Verified by [ID.registered_name] ([ID.assignment])"
			updateUsrDialog()
		if(screen == 10)
			if (access_RC_announce in ID.access)
				announceAuth = 1
			else
				announceAuth = 0
				user << "You are not authorized to send announcements!"
			updateUsrDialog()
	if (istype(O, /obj/item/weapon/stamp))
		if(screen == 9)
			var/obj/item/weapon/stamp/T = O
			msgStamped = "Stamped with the [T.name]"
			updateUsrDialog()
	return


code:
/obj/machinery/robotic_fabricator
	name = "robotic fabricator"
	icon = 'icons/obj/robotics.dmi'
	icon_state = "fab-idle"
	density = 1
	anchored = 1
	var/metal_amount = 0
	var/operating = 0
	var/obj/item/robot_parts/being_built = null
	use_power = 1
	idle_power_usage = 20
	active_power_usage = 5000

/obj/machinery/robotic_fabricator/attackby(obj/item/O, mob/user, params)
	if (istype(O, /obj/item/stack/sheet/metal))
		if (src.metal_amount < 150000)
			var/count = 0
			src.overlays += "fab-load-metal"
			spawn(15)
				if(O)
					if(!O:amount)
						return
					while(metal_amount < 150000 && O:amount)
						src.metal_amount += O:materials[MAT_METAL] /*O:height * O:width * O:length * 100000*/
						O:amount--
						count++

					if (O:amount < 1)
						qdel(O)

					user << "You insert [count] metal sheet\s into \the [src]."
					src.overlays -= "fab-load-metal"
					updateDialog()
		else
			user << "\The [src] is full."

/obj/machinery/robotic_fabricator/power_change()
	if (powered())
		stat &= ~NOPOWER
	else
		stat |= NOPOWER

/obj/machinery/robotic_fabricator/attack_paw(mob/user)
	return src.attack_hand(user)

/obj/machinery/robotic_fabricator/attack_hand(mob/user)
	var/dat
	if (..())
		return

	if (src.operating)
		dat = {"
<TT>Building [src.being_built.name].

Please wait until completion...</TT>

"}
	else
		dat = {"
Metal Amount: [min(150000, src.metal_amount)] cm3 (MAX: 150,000)

Left Arm (25,000 cc metal.)

Right Arm (25,000 cc metal.)

Left Leg (25,000 cc metal.)

Right Leg (25,000 cc metal).

Chest (50,000 cc metal).

Head (50,000 cc metal).

Robot Frame (75,000 cc metal).

"}

	user << browse("<TITLE>Robotic Fabricator Control Panel</TITLE><TT>[dat]</TT>", "window=robot_fabricator")
	onclose(user, "robot_fabricator")
	return

/obj/machinery/robotic_fabricator/Topic(href, href_list)
	if (..())
		return

	usr.set_machine(src)
	src.add_fingerprint(usr)

	if (href_list["make"])
		if (!src.operating)
			var/part_type = text2num(href_list["make"])

			var/build_type = ""
			var/build_time = 200
			var/build_cost = 25000

			switch (part_type)
				if (1)
					build_type = "/obj/item/robot_parts/l_arm"
					build_time = 200
					build_cost = 10000

				if (2)
					build_type = "/obj/item/robot_parts/r_arm"
					build_time = 200
					build_cost = 10000

				if (3)
					build_type = "/obj/item/robot_parts/l_leg"
					build_time = 200
					build_cost = 10000

				if (4)
					build_type = "/obj/item/robot_parts/r_leg"
					build_time = 200
					build_cost = 10000

				if (5)
					build_type = "/obj/item/robot_parts/chest"
					build_time = 350
					build_cost = 40000

				if (6)
					build_type = "/obj/item/robot_parts/head"
					build_time = 350
					build_cost = 5000

				if (7)
					build_type = "/obj/item/robot_parts/robot_suit"
					build_time = 600
					build_cost = 15000

			var/building = text2path(build_type)
			if (!isnull(building))
				if (src.metal_amount >= build_cost)
					src.operating = 1
					src.use_power = 2

					src.metal_amount = max(0, src.metal_amount - build_cost)

					src.being_built = new building(src)

					src.overlays += "fab-active"
					src.updateUsrDialog()

					spawn (build_time)
						if (!isnull(src.being_built))
							src.being_built.loc = get_turf(src)
							src.being_built = null
						src.use_power = 1
						src.operating = 0
						src.overlays -= "fab-active"
		return

	for (var/mob/M in viewers(1, src))
		if (M.client && M.machine == src)
			src.attack_hand(M)


code:
/obj/machinery/shield
		name = "emergency energy shield"
		desc = "An energy shield used to contain hull breaches."
		icon = 'icons/effects/effects.dmi'
		icon_state = "shield-old"
		density = 1
		opacity = 0
		anchored = 1
		unacidable = 1
		var/const/max_health = 200
		var/health = max_health //The shield can only take so much beating (prevents perma-prisons)

/obj/machinery/shield/New()
	src.dir = pick(1,2,3,4)
	..()
	air_update_turf(1)

/obj/machinery/shield/Destroy()
	opacity = 0
	density = 0
	air_update_turf(1)
	return ..()

/obj/machinery/shield/Move()
	var/turf/T = loc
	..()
	move_update_air(T)

/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height)
	if(!height) return 0
	else return ..()

/obj/machinery/shield/CanAtmosPass(turf/T)
	return !density

/obj/machinery/shield/attackby(obj/item/weapon/W, mob/user, params)
	..()
	if(W.damtype == BRUTE || W.damtype == BURN)
		take_damage(W.force)

/obj/machinery/shield/bullet_act(obj/item/projectile/Proj)
	..()
	take_damage(Proj.damage)

/obj/machinery/shield/ex_act(severity, target)
	switch(severity)
		if(1)
			if (prob(75))
				qdel(src)
		if(2)
			if (prob(50))
				qdel(src)
		if(3)
			if (prob(25))
				qdel(src)
	return

/obj/machinery/shield/emp_act(severity)
	switch(severity)
		if(1)
			qdel(src)
		if(2)
			if(prob(50))
				qdel(src)

/obj/machinery/shield/blob_act()
	qdel(src)

/obj/machinery/shield/hitby(AM as mob|obj)
	var/tforce = 0
	if(ismob(AM))
		tforce = 40
	else
		var/obj/O = AM
		tforce = O.throwforce
	..()
	take_damage(tforce)

/obj/machinery/shield/proc/take_damage(damage)
	playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
	opacity = 1
	spawn(20)
		opacity = 0
	health -= damage
	if(health <= 0)
		visible_message("[src] dissipates.")
		qdel(src)

/obj/machinery/shieldgen
		name = "anti-breach shielding projector"
		desc = "Used to seal minor hull breaches."
		icon = 'icons/obj/objects.dmi'
		icon_state = "shieldoff"
		density = 1
		opacity = 0
		anchored = 0
		pressure_resistance = 2*ONE_ATMOSPHERE
		req_access = list(access_engine)
		var/const/max_health = 100
		var/health = max_health
		var/active = 0
		var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate
		var/list/deployed_shields = list()
		var/is_open = 0 //Whether or not the wires are exposed
		var/locked = 0
		var/shield_range = 4

/obj/machinery/shieldgen/Destroy()
	for(var/obj/machinery/shield/shield_tile in deployed_shields)
		qdel(shield_tile)
	deployed_shields = null
	return ..()

/obj/machinery/shieldgen/proc/shields_up()
	if(active) return 0 //If it's already turned on, how did this get called?

	src.active = 1
	update_icon()

	for(var/turf/target_tile in range(shield_range, src))
		if (istype(target_tile,/turf/open/space) && !(locate(/obj/machinery/shield) in target_tile))
			if (malfunction && prob(33) || !malfunction)
				deployed_shields += new /obj/machinery/shield(target_tile)

/obj/machinery/shieldgen/proc/shields_down()
	if(!active) return 0 //If it's already off, how did this get called?

	src.active = 0
	update_icon()

	for(var/obj/machinery/shield/shield_tile in deployed_shields)
		qdel(shield_tile)
	deployed_shields.Cut()

/obj/machinery/shieldgen/process()
	if(malfunction && active)
		if(deployed_shields.len && prob(5))
			qdel(pick(deployed_shields))

	return

/obj/machinery/shieldgen/proc/checkhp()
	if(health <= 30)
		src.malfunction = 1
	if(health <= 0)
		qdel(src)
	update_icon()
	return

/obj/machinery/shieldgen/ex_act(severity, target)
	switch(severity)
		if(1)
			src.health -= 75
			src.checkhp()
		if(2)
			src.health -= 30
			if (prob(15))
				src.malfunction = 1
			src.checkhp()
		if(3)
			src.health -= 10
			src.checkhp()
	return

/obj/machinery/shieldgen/emp_act(severity)
	switch(severity)
		if(1)
			src.health /= 2 //cut health in half
			malfunction = 1
			locked = pick(0,1)
		if(2)
			if(prob(50))
				src.health *= 0.3 //chop off a third of the health
				malfunction = 1
	checkhp()

/obj/machinery/shieldgen/attack_hand(mob/user)
	if(locked)
		user << "The machine is locked, you are unable to use it!"
		return
	if(is_open)
		user << "The panel must be closed before operating this machine!"
		return

	if (src.active)
		user.visible_message("[user] deactivated \the [src].", \
			"You deactivate \the [src].", \
			"You hear heavy droning fade out.")
		src.shields_down()
	else
		if(anchored)
			user.visible_message("[user] activated \the [src].", \
				"You activate \the [src].", \
				"You hear heavy droning.")
			src.shields_up()
		else
			user << "The device must first be secured to the floor!"
	return

/obj/machinery/shieldgen/attackby(obj/item/weapon/W, mob/user, params)
	if(istype(W, /obj/item/weapon/screwdriver))
		playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
		if(is_open)
			user << "You close the panel."
			is_open = 0
		else
			user << "You open the panel and expose the wiring."
			is_open = 1

	else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open)
		var/obj/item/stack/cable_coil/coil = W
		if (coil.get_amount() < 1)
			user << "You need one length of cable to repair [src]!"
			return
		user << "You begin to replace the wires..."
		if(do_after(user, 30, target = src))
			if(coil.get_amount() < 1)
				return
			coil.use(1)
			health = max_health
			malfunction = 0
			user << "You repair \the [src]."
			update_icon()

	else if(istype(W, /obj/item/weapon/wrench))
		if(locked)
			user << "The bolts are covered! Unlocking this would retract the covers."
			return
		if(!anchored && !isinspace())
			playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
			user << "You secure \the [src] to the floor!"
			anchored = 1
		else if(anchored)
			playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
			user << "You unsecure \the [src] from the floor!"
			if(active)
				user << "\The [src] shuts off!"
				src.shields_down()
			anchored = 0

	else if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
		if(src.allowed(user))
			src.locked = !src.locked
			user << "You [src.locked ? "lock" : "unlock"] the controls."
		else
			user << "Access denied."

	else
		..()

/obj/machinery/shieldgen/emag_act()
	if(!malfunction)
		malfunction = 1
		update_icon()

/obj/machinery/shieldgen/update_icon()
	if(active)
		src.icon_state = malfunction ? "shieldonbr":"shieldon"
	else
		src.icon_state = malfunction ? "shieldoffbr":"shieldoff"
	return

////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille
#define maxstoredpower 500
/obj/machinery/shieldwallgen
		name = "shield generator"
		desc = "A shield generator."
		icon = 'icons/obj/stationobjs.dmi'
		icon_state = "Shield_Gen"
		anchored = 0
		density = 1
		req_access = list(access_teleporter)
		var/active = 0
		var/power = 0
		var/steps = 0
		var/last_check = 0
		var/check_delay = 10
		var/recalc = 0
		var/locked = 1
		var/destroyed = 0
//		var/maxshieldload = 200
		var/obj/structure/cable/attached		// the attached cable
		var/storedpower = 0
		flags = CONDUCT
		use_power = 0

/obj/machinery/shieldwallgen/proc/power()
	if(!anchored)
		power = 0
		return 0
	var/turf/T = src.loc

	var/obj/structure/cable/C = T.get_cable_node()
	var/datum/powernet/PN
	if(C)
		PN = C.powernet		// find the powernet of the connected cable

	if(!PN)
		power = 0
		return 0

	var/surplus = max(PN.avail-PN.load, 0)
	var/shieldload = min(rand(50,200), surplus)
	if(shieldload==0 && !storedpower)		// no cable or no power, and no power stored
		power = 0
		return 0
	else
		power = 1	// IVE GOT THE POWER!
		if(PN) //runtime errors fixer. They were caused by PN.newload trying to access missing network in case of working on stored power.
			storedpower += shieldload
			PN.load += shieldload //uses powernet power.
//		message_admins("[PN.load]")
//		use_power(250) //uses APC power

/obj/machinery/shieldwallgen/attack_hand(mob/user)
	if(!anchored)
		user << "\The [src] needs to be firmly secured to the floor first!"
		return 1
	if(locked && !istype(user, /mob/living/silicon))
		user << "The controls are locked!"
		return 1
	if(power != 1)
		user << "\The [src] needs to be powered by wire underneath!"
		return 1

	if(src.active >= 1)
		src.active = 0
		icon_state = "Shield_Gen"

		user.visible_message("[user] turned \the [src] off.", \
			"You turn off \the [src].", \
			"You hear heavy droning fade out.")
		src.cleanup()
	else
		src.active = 1
		icon_state = "Shield_Gen +a"
		user.visible_message("[user] turned \the [src] on.", \
			"You turn on \the [src].", \
			"You hear heavy droning.")
	src.add_fingerprint(user)

/obj/machinery/shieldwallgen/process()
	power()
	if(power)
		storedpower -= 50 //this way it can survive longer and survive at all
	if(storedpower >= maxstoredpower)
		storedpower = maxstoredpower
	if(storedpower <= 0)
		storedpower = 0
//	if(shieldload >= maxshieldload) //there was a loop caused by specifics of process(), so this was needed.
//		shieldload = maxshieldload

	if(src.active == 1)
		if(!anchored)
			src.active = 0
			return
		setup_field(1)
		setup_field(2)
		setup_field(4)
		setup_field(8)
		src.active = 2
	if(src.active >= 1)
		if(src.power == 0)
			src.visible_message("The [src.name] shuts down due to lack of power!", \
				"You hear heavy droning fade out.")
			icon_state = "Shield_Gen"
			src.active = 0
			src.cleanup(1)
			src.cleanup(2)
			src.cleanup(4)
			src.cleanup(8)

/obj/machinery/shieldwallgen/proc/setup_field(NSEW = 0)
	var/turf/T = src.loc
	var/turf/T2 = src.loc
	var/obj/machinery/shieldwallgen/G
	var/steps = 0
	var/oNSEW = 0

	if(!NSEW)//Make sure its ran right
		return

	if(NSEW == 1)
		oNSEW = 2
	else if(NSEW == 2)
		oNSEW = 1
	else if(NSEW == 4)
		oNSEW = 8
	else if(NSEW == 8)
		oNSEW = 4

	for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
		T = get_step(T2, NSEW)
		T2 = T
		steps += 1
		if(locate(/obj/machinery/shieldwallgen) in T)
			G = (locate(/obj/machinery/shieldwallgen) in T)
			steps -= 1
			if(!G.active)
				return
			G.cleanup(oNSEW)
			break

	if(isnull(G))
		return

	T2 = src.loc

	for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
		var/field_dir = get_dir(T2,get_step(T2, NSEW))
		T = get_step(T2, NSEW)
		T2 = T
		var/obj/machinery/shieldwall/CF = new/obj/machinery/shieldwall/(src, G) //(ref to this gen, ref to connected gen)
		CF.loc = T
		CF.dir = field_dir

/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user, params)
	if(istype(W, /obj/item/weapon/wrench))
		if(active)
			user << "Turn off the field generator first!"
			return

		else if(!anchored && !isinspace()) //Can't fasten this thing in space
			playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
			user << "You secure the external reinforcing bolts to the floor."
			anchored = 1
			return

		else //You can unfasten it tough, if you somehow manage to fasten it.
			playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
			user << "You undo the external reinforcing bolts."
			anchored = 0
			return

	if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
		if (src.allowed(user))
			src.locked = !src.locked
			user << "You [src.locked ? "lock" : "unlock"] the controls."
		else
			user << "Access denied."

	else
		add_fingerprint(user)
		..()

/obj/machinery/shieldwallgen/proc/cleanup(NSEW)
	var/obj/machinery/shieldwall/F
	var/obj/machinery/shieldwallgen/G
	var/turf/T = src.loc
	var/turf/T2 = src.loc

	for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for fields
		T = get_step(T2, NSEW)
		T2 = T
		if(locate(/obj/machinery/shieldwall) in T)
			F = (locate(/obj/machinery/shieldwall) in T)
			qdel(F)

		if(locate(/obj/machinery/shieldwallgen) in T)
			G = (locate(/obj/machinery/shieldwallgen) in T)
			if(!G.active)
				break

/obj/machinery/shieldwallgen/Destroy()
	src.cleanup(1)
	src.cleanup(2)
	src.cleanup(4)
	src.cleanup(8)
	return ..()

/obj/machinery/shieldwallgen/bullet_act(obj/item/projectile/Proj)
	storedpower -= Proj.damage
	..()

//////////////Containment Field START
/obj/machinery/shieldwall
		name = "shield"
		desc = "An energy shield."
		icon = 'icons/effects/effects.dmi'
		icon_state = "shieldwall"
		anchored = 1
		density = 1
		unacidable = 1
		luminosity = 3
		var/needs_power = 0
		var/active = 1
		var/delay = 5
		var/last_active
		var/mob/U
		var/obj/machinery/shieldwallgen/gen_primary
		var/obj/machinery/shieldwallgen/gen_secondary

/obj/machinery/shieldwall/New(var/obj/machinery/shieldwallgen/A, var/obj/machinery/shieldwallgen/B)
	..()
	src.gen_primary = A
	src.gen_secondary = B
	if(A && B)
		needs_power = 1
	for(var/mob/living/L in get_turf(src.loc))
		visible_message("\The [src] is suddenly occupying the same space as \the [L]'s organs!")
		L.gib()

/obj/machinery/shieldwall/attack_hand(mob/user)
	return

/obj/machinery/shieldwall/process()
	if(needs_power)
		if(isnull(gen_primary)||isnull(gen_secondary))
			qdel(src)
			return

		if(!(gen_primary.active)||!(gen_secondary.active))
			qdel(src)
			return

		if(prob(50))
			gen_primary.storedpower -= 10
		else
			gen_secondary.storedpower -=10

/obj/machinery/shieldwall/bullet_act(obj/item/projectile/Proj)
	if(needs_power)
		var/obj/machinery/shieldwallgen/G
		if(prob(50))
			G = gen_primary
		else
			G = gen_secondary
		G.storedpower -= Proj.damage
	..()
	return

/obj/machinery/shieldwall/ex_act(severity, target)
	if(needs_power)
		var/obj/machinery/shieldwallgen/G
		switch(severity)
			if(1) //big boom
				if(prob(50))
					G = gen_primary
				else
					G = gen_secondary
				G.storedpower -= 200

			if(2) //medium boom
				if(prob(50))
					G = gen_primary
				else
					G = gen_secondary
				G.storedpower -= 50

			if(3) //lil boom
				if(prob(50))
					G = gen_primary
				else
					G = gen_secondary
				G.storedpower -= 20
	return

/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0)
	if(height==0) return 1

	if(istype(mover) && mover.checkpass(PASSGLASS))
		return prob(20)
	else
		if (istype(mover, /obj/item/projectile))
			return prob(10)
		else
			return !src.density


code:
/*******************************\
|		  Slot Machines		  	|
|	  Original code by Glloyd	|
|	  Tgstation port by Miauw	|
\*******************************/

#define SPIN_PRICE 5
#define SMALL_PRIZE 400
#define BIG_PRIZE 1000
#define JACKPOT 10000
#define SPIN_TIME 65 //As always, deciseconds.
#define REEL_DEACTIVATE_DELAY 7
#define SEVEN "7"

/obj/machinery/computer/slot_machine
	name = "slot machine"
	desc = "Gambling for the antisocial."
	icon = 'icons/obj/economy.dmi'
	icon_state = "slots1"
	anchored = 1
	density = 1
	use_power = 1
	idle_power_usage = 50
	circuit = /obj/item/weapon/circuitboard/slot_machine
	var/money = 3000 //How much money it has CONSUMED
	var/plays = 0
	var/working = 0
	var/balance = 0 //How much money is in the machine, ready to be CONSUMED.
	var/jackpots = 0
	var/list/coinvalues = list()
	var/list/reels = list(list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0)
	var/list/symbols = list(SEVEN = 1, "&" = 2, "@" = 2, "$" = 2, "?" = 2, "#" = 2, "!" = 2, "%" = 2) //if people are winning too much, multiply every number in this list by 2 and see if they are still winning too much.

/obj/machinery/computer/slot_machine/New()
	..()
	jackpots = rand(1, 4) //false hope
	plays = rand(75, 200)

	toggle_reel_spin(1) //The reels won't spin unless we activate them

	var/list/reel = reels[1]
	for(var/i = 0, i < reel.len, i++) //Populate the reels.
		randomize_reels()

	toggle_reel_spin(0)

	for(var/cointype in typesof(/obj/item/weapon/coin))
		var/obj/item/weapon/coin/C = new cointype(src)
		coinvalues["[cointype]"] = C.value
		qdel(C)

/obj/machinery/computer/slot_machine/process()
	. = ..() //Sanity checks.
	if(!.)
		return .

	money++ //SPESSH MAJICKS

/obj/machinery/computer/slot_machine/update_icon()
	if(stat & NOPOWER)
		icon_state = "slots0"

	else if(stat & BROKEN)
		icon_state = "slotsb"

	else if(working)
		icon_state = "slots2"

	else
		icon_state = "slots1"

/obj/machinery/computer/slot_machine/power_change()
	..()
	update_icon()

/obj/machinery/computer/slot_machine/attackby(obj/item/I, mob/living/user, params)
	if(istype(I, /obj/item/weapon/coin))
		var/obj/item/weapon/coin/C = I
		if(prob(2))
			if(!user.drop_item())
				return
			C.loc = loc
			C.throw_at(user, 3, 10)
			if(prob(10))
				balance = max(balance - SPIN_PRICE, 0)
			user << "[src] spits your coin back out!"

		else
			if(!user.drop_item())
				return
			user << "You insert a [C.cmineral] coin into [src]'s slot!"
			balance += C.value
			qdel(C)

		return

	else if(!balance) //to prevent coins from magically disappearing
		..()

/obj/machinery/computer/slot_machine/emag_act()
	if(!emagged)
		emagged = 1
		var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
		spark_system.set_up(4, 0, src.loc)
		spark_system.start()
		playsound(src.loc, "sparks", 50, 1)

/obj/machinery/computer/slot_machine/attack_hand(mob/living/user)
	. = ..() //Sanity checks.
	if(.)
		return .

	interact(user)

/obj/machinery/computer/slot_machine/interact(mob/living/user)
	var/reeltext = {"
	/*****^*****^*****^*****^*****\\

	| \[[reels[1][1]]\] | \[[reels[2][1]]\] | \[[reels[3][1]]\] | \[[reels[4][1]]\] | \[[reels[5][1]]\] |

	| \[[reels[1][2]]\] | \[[reels[2][2]]\] | \[[reels[3][2]]\] | \[[reels[4][2]]\] | \[[reels[5][2]]\] |

	| \[[reels[1][3]]\] | \[[reels[2][3]]\] | \[[reels[3][3]]\] | \[[reels[4][3]]\] | \[[reels[5][3]]\] |

	\\*****v*****v*****v*****v*****/

	"}

	var/dat
	if(working)
		dat = reeltext

	else
		dat = {"Five credits to play!

		Prize Money Available: [money] (jackpot payout is ALWAYS 100%!)

		Credit Remaining: [balance]

		[plays] players have tried their luck today, and [jackpots] have won a jackpot!

		Play!

		[reeltext]

		Refund balance
"}

	var/datum/browser/popup = new(user, "slotmachine", "Slot Machine")
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
	popup.open()

/obj/machinery/computer/slot_machine/Topic(href, href_list)
	. = ..() //Sanity checks.
	if(.)
		return .

	if(href_list["spin"])
		spin(usr)

	else if(href_list["refund"])
		give_coins(balance)
		balance = 0

/obj/machinery/computer/slot_machine/emp_act(severity)
	if(stat & (NOPOWER|BROKEN))
		return
	if(prob(15 * severity))
		return
	if(prob(1)) // :^)
		emagged = 1
	var/severity_ascending = 4 - severity
	money = max(rand(money - (200 * severity_ascending), money + (200 * severity_ascending)), 0)
	balance = max(rand(balance - (50 * severity_ascending), balance + (50 * severity_ascending)), 0)
	money -= max(0, give_coins(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo
	spin()

/obj/machinery/computer/slot_machine/proc/spin(mob/user)
	if(!can_spin(user))
		return

	var/the_name
	if(user)
		the_name = user.real_name
		visible_message("[user] pulls the lever and the slot machine starts spinning!")
	else
		the_name = "Exaybachay"

	balance -= SPIN_PRICE
	money += SPIN_PRICE
	plays += 1
	working = 1

	toggle_reel_spin(1)
	update_icon()
	updateDialog()

	spawn(0)
		while(working)
			randomize_reels()
			updateDialog()
			sleep(2)

	spawn(SPIN_TIME - (REEL_DEACTIVATE_DELAY * reels.len)) //WARNING: no sanity checking for user since it's not needed and would complicate things (machine should still spin even if user is gone), be wary of this if you're changing this code.
		toggle_reel_spin(0, REEL_DEACTIVATE_DELAY)
		working = 0
		give_prizes(the_name, user)
		update_icon()
		updateDialog()

/obj/machinery/computer/slot_machine/proc/can_spin(mob/user)
	if(stat & NOPOWER)
		user << "The slot machine has no power!"
	if(stat & BROKEN)
		user << "The slot machine is broken!"
	if(working)
		user << "You need to wait until the machine stops spinning before you can play again!"
		return 0
	if(balance < SPIN_PRICE)
		user << "Insufficient money to play!"
		return 0
	return 1

/obj/machinery/computer/slot_machine/proc/toggle_reel_spin(value, delay = 0) //value is 1 or 0 aka on or off
	for(var/list/reel in reels)
		reels[reel] = value
		sleep(delay)

/obj/machinery/computer/slot_machine/proc/randomize_reels()

	for(var/reel in reels)
		if(reels[reel])
			reel[3] = reel[2]
			reel[2] = reel[1]
			reel[1] = pick(symbols)

/obj/machinery/computer/slot_machine/proc/give_prizes(usrname, mob/user)
	var/linelength = get_lines()

	if(reels[1][2] + reels[2][2] + reels[3][2] + reels[4][2] + reels[5][2] == "[SEVEN][SEVEN][SEVEN][SEVEN][SEVEN]")
		visible_message("[src] says, 'JACKPOT! You win [money] credits worth of coins!'")
		priority_announce("Congratulations to [user ? user.real_name : usrname] for winning the jackpot at the slot machine in [get_area(src)]!")
		jackpots += 1
		balance += money - give_coins(JACKPOT)
		money = 0

		for(var/i = 0, i < 5, i++)
			var/cointype = pick(subtypesof(/obj/item/weapon/coin))
			var/obj/item/weapon/coin/C = new cointype(loc)
			random_step(C, 2, 50)

	else if(linelength == 5)
		visible_message("[src] says, 'Big Winner! You win a thousand credits worth of coins!'")
		give_money(BIG_PRIZE)

	else if(linelength == 4)
		visible_message("[src] says, 'Winner! You win four hundred credits worth of coins!'")
		give_money(SMALL_PRIZE)

	else if(linelength == 3)
		user << "You win three free games!"
		balance += SPIN_PRICE * 4
		money = max(money - SPIN_PRICE * 4, money)

	else
		user << "No luck!"

/obj/machinery/computer/slot_machine/proc/get_lines()
	var/amountthesame

	for(var/i = 1, i <= 3, i++)
		var/inputtext = reels[1][i] + reels[2][i] + reels[3][i] + reels[4][i] + reels[5][i]
		for(var/symbol in symbols)
			var/j = 3 //The lowest value we have to check for.
			var/symboltext = symbol + symbol + symbol
			while(j <= 5)
				if(findtext(inputtext, symboltext))
					amountthesame = max(j, amountthesame)
				j++
				symboltext += symbol

			if(amountthesame)
				break

	return amountthesame

/obj/machinery/computer/slot_machine/proc/give_money(amount)
	var/amount_to_give = money >= amount ? amount : money
	var/surplus = amount_to_give - give_coins(amount_to_give)
	money = max(0, money - amount)
	balance += surplus

/obj/machinery/computer/slot_machine/proc/give_coins(amount)
	var/cointype = emagged ? /obj/item/weapon/coin/iron : /obj/item/weapon/coin/silver

	if(!emagged)
		amount = dispense(amount, cointype, null, 0)

	else
		var/mob/living/target = locate() in range(2, src)

		amount = dispense(amount, cointype, target, 1)

	return amount

/obj/machinery/computer/slot_machine/proc/dispense(amount = 0, cointype = /obj/item/weapon/coin/silver, mob/living/target, throwit = 0)
	var/value = coinvalues["[cointype]"]

	while(amount >= value)
		var/obj/item/weapon/coin/C = new cointype(loc) //DOUBLE THE PAIN
		amount -= value
		if(throwit && target)
			C.throw_at(target, 3, 10)
		else
			random_step(C, 2, 40)

	return amount

#undef SEVEN
#undef SPIN_TIME
#undef JACKPOT
#undef BIG_PRIZE
#undef SMALL_PRIZE
#undef SPIN_PRICE


code:
#define HEATER_MODE_STANDBY	"standby"
#define HEATER_MODE_HEAT	"heat"
#define HEATER_MODE_COOL	"cool"

/obj/machinery/space_heater
	anchored = 0
	density = 1
	interact_open = TRUE
	icon = 'icons/obj/atmos.dmi'
	icon_state = "sheater-off"
	name = "space heater"
	desc = "Made by Space Amish using traditional space techniques, this heater/cooler is guaranteed not to set the station on fire."
	var/obj/item/weapon/stock_parts/cell/cell
	var/on = FALSE
	var/mode = HEATER_MODE_STANDBY
	var/setMode = "auto" // Anything other than "heat" or "cool" is considered auto.
	var/targetTemperature = T20C
	var/heatingPower = 40000
	var/efficiency = 20000
	var/temperatureTolerance = 1
	var/settableTemperatureMedian = 30 + T0C
	var/settableTemperatureRange = 30

/obj/machinery/space_heater/New()
	..()
	cell = new(src)
	component_parts = list()
	component_parts += new /obj/item/weapon/circuitboard/space_heater(null)
	component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
	component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
	component_parts += new /obj/item/stack/cable_coil(null, 3)
	RefreshParts()
	update_icon()

/obj/machinery/space_heater/construction()
	qdel(cell)
	cell = null
	panel_open = TRUE
	update_icon()
	return ..()

/obj/machinery/space_heater/deconstruction()
	if(cell)
		component_parts += cell
		cell = null
	return ..()

/obj/machinery/space_heater/examine(mob/user)
	..()
	user << "\The [src] is [on ? "on" : "off"], and the hatch is [panel_open ? "open" : "closed"]."
	if(cell)
		user << "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%."
	else
		user << "There is no power cell installed."

/obj/machinery/space_heater/update_icon()
	if(on)
		icon_state = "sheater-[mode]"
	else
		icon_state = "sheater-off"

	overlays.Cut()
	if(panel_open)
		overlays += "sheater-open"

/obj/machinery/space_heater/process()
	if(!on || !is_operational())
		return

	if(cell && cell.charge > 0)
		var/turf/L = loc
		if(!istype(L))
			if(mode != HEATER_MODE_STANDBY)
				mode = HEATER_MODE_STANDBY
				update_icon()
			return

		var/datum/gas_mixture/env = L.return_air()

		var/newMode = HEATER_MODE_STANDBY
		if(setMode != HEATER_MODE_COOL && env.temperature < targetTemperature - temperatureTolerance)
			newMode = HEATER_MODE_HEAT
		else if(setMode != HEATER_MODE_HEAT && env.temperature > targetTemperature + temperatureTolerance)
			newMode = HEATER_MODE_COOL

		if(mode != newMode)
			mode = newMode
			update_icon()

		if(mode == HEATER_MODE_STANDBY)
			return

		var/heat_capacity = env.heat_capacity()
		var/requiredPower = abs(env.temperature - targetTemperature) * heat_capacity
		requiredPower = min(requiredPower, heatingPower)

		if(requiredPower < 1)
			return

		var/deltaTemperature = requiredPower / heat_capacity
		if(mode == HEATER_MODE_COOL)
			deltaTemperature *= -1
		if(deltaTemperature)
			env.temperature += deltaTemperature
			air_update_turf()
		cell.use(requiredPower / efficiency)
	else
		on = FALSE
		update_icon()

/obj/machinery/space_heater/RefreshParts()
	var/laser = 0
	var/cap = 0
	for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
		laser += M.rating
	for(var/obj/item/weapon/stock_parts/capacitor/M in component_parts)
		cap += M.rating

	heatingPower = laser * 40000

	settableTemperatureRange = cap * 30
	efficiency = (cap + 1) * 10000

	targetTemperature = Clamp(targetTemperature,
		max(settableTemperatureMedian - settableTemperatureRange, TCMB),
		settableTemperatureMedian + settableTemperatureRange)

/obj/machinery/space_heater/emp_act(severity)
	if(stat & (BROKEN|NOPOWER))
		..(severity)
		return
	if(cell)
		cell.emp_act(severity)
	..(severity)

/obj/machinery/space_heater/attackby(obj/item/I, mob/user, params)
	add_fingerprint(user)
	if(istype(I, /obj/item/weapon/stock_parts/cell))
		if(panel_open)
			if(cell)
				user << "There is already a power cell inside!"
				return
			else
				// insert cell
				var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
				if(istype(C))
					if(!user.drop_item())
						return
					cell = C
					C.loc = src
					C.add_fingerprint(usr)

					user.visible_message("\The [user] inserts a power cell into \the [src].", "You insert the power cell into \the [src].")
					SStgui.update_uis(src)
		else
			user << "The hatch must be open to insert a power cell!"
			return
	else if(istype(I, /obj/item/weapon/screwdriver))
		panel_open = !panel_open
		user.visible_message("\The [user] [panel_open ? "opens" : "closes"] the hatch on \the [src].", "You [panel_open ? "open" : "close"] the hatch on \the [src].")
		update_icon()
		if(panel_open)
			interact(user)
	else if(exchange_parts(user, I) || default_deconstruction_crowbar(I))
		return
	else
		..()

/obj/machinery/space_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
										datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
	ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
	if(!ui)
		ui = new(user, src, ui_key, "space_heater", name, 400, 305, master_ui, state)
		ui.open()

/obj/machinery/space_heater/ui_data()
	var/list/data = list()
	data["open"] = panel_open
	data["on"] = on
	data["mode"] = setMode
	data["hasPowercell"] = !!cell
	if(cell)
		data["powerLevel"] = round(cell.percent(), 1)
	data["targetTemp"] = round(targetTemperature - T0C, 1)
	data["minTemp"] = max(settableTemperatureMedian - settableTemperatureRange - T0C, TCMB)
	data["maxTemp"] = settableTemperatureMedian + settableTemperatureRange - T0C

	var/turf/L = get_turf(loc)
	var/curTemp
	if(istype(L))
		var/datum/gas_mixture/env = L.return_air()
		curTemp = env.temperature
	else if(isturf(L))
		curTemp = L.temperature
	if(isnull(curTemp))
		data["currentTemp"] = "N/A"
	else
		data["currentTemp"] = round(curTemp - T0C, 1)
	return data

/obj/machinery/space_heater/ui_act(action, params)
	if(..())
		return
	switch(action)
		if("power")
			on = !on
			mode = HEATER_MODE_STANDBY
			usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", "You switch [on ? "on" : "off"] \the [src].")
			update_icon()
			. = TRUE
		if("mode")
			setMode = params["mode"]
			. = TRUE
		if("target")
			if(!panel_open)
				return
			var/target = params["target"]
			var/adjust = text2num(params["adjust"])
			if(target == "input")
				target = input("New target temperature:", name, round(targetTemperature - T0C, 1)) as num|null
				if(!isnull(target) && !..())
					. = TRUE
			else if(adjust)
				target = targetTemperature + adjust
				. = TRUE
			else if(text2num(target) != null)
				target= text2num(target) + T0C
				. = TRUE
			if(.)
				targetTemperature = Clamp(round(target),
					max(settableTemperatureMedian - settableTemperatureRange, TCMB),
					settableTemperatureMedian + settableTemperatureRange)
		if("eject")
			if(panel_open && cell)
				cell.loc = get_turf(src)
				cell = null
				. = TRUE

#undef HEATER_MODE_STANDBY
#undef HEATER_MODE_HEAT
#undef HEATER_MODE_COOL