code:
//These procs handle putting stuff in your hand. It's probably best to use these rather than setting stuff manually
//as they handle all relevant stuff like adding it to the player's screen and such

//Returns the thing in our active hand (whatever is in our active module-slot, in this case)
/mob/living/silicon/robot/mommi/get_active_hand()
	return module_active

/mob/living/silicon/robot/mommi/proc/is_in_modules(obj/item/W, var/permit_sheets=0)
	if(istype(W, src.module.emag.type))
		return src.module.emag
	// Exact matching for stacks (so we can load machines)
	if(istype(W, /obj/item/stack/sheet))
		for(var/obj/item/stack/sheet/S in src.module.modules)
			if(S.type==W.type)
				return permit_sheets ? 0 : S
	else
		return locate(W) in src.module.modules

/mob/living/silicon/robot/mommi/activate_module(var/obj/item/O)
	if(!(locate(O) in src.module.modules) && O != src.module.emag)
		return
	if(activated(O))
		src << "Already activated"
		return
	if(!tool_state)
		tool_state = O
		O.layer = 20
		contents += O
		select_module(INV_SLOT_TOOL)
		update_items()
	else
		src << "You need to store a module first!"

/mob/living/silicon/robot/mommi/toggle_module() //Only one module

	if(module_selected(INV_SLOT_TOOL))
		deselect_module(INV_SLOT_TOOL)
		update_items()
	else
		select_module(INV_SLOT_TOOL)
		update_items()
	return

/mob/living/silicon/robot/mommi/put_in_hands(var/obj/item/W)
	// Fixing NPEs caused by PDAs giving me NULLs to hold :V - N3X
	// And before you ask, this is how /mob handles NULLs, too.
	if(!W)
		return 0
	// Make sure we're not picking up something that's in our factory-supplied toolbox.
	//if(is_type_in_list(W,src.module.modules))
	if(is_in_modules(W))
		src << "\red Picking up something that's built-in to you seems a bit silly."
		return 0
	if(tool_state)
		//var/obj/item/found = locate(tool_state) in src.module.modules
		W.loc = get_turf(src)
		W.layer = initial(W.layer)
		W.dropped()
		return 0
	tool_state = W
	W.layer = 20
	contents += W
	update_items()

	// Make crap we pick up active so there's less clicking and carpal. - N3X
	module_active=tool_state
	inv_tool.icon_state = "inv1 +a"
	//inv_sight.icon_state = "sight"

	update_items()
	return 1

//Attemps to remove an object on a mob.  Will not move it to another area or such, just removes from the mob.
/mob/living/silicon/robot/mommi/remove_from_mob(var/obj/O)
	src.u_equip(O)
	if (src.client)
		src.client.screen -= O
	O.layer = initial(O.layer)
	O.screen_loc = null
	return 1

/mob/living/silicon/robot/mommi/proc/u_equip(W as obj)
	unEquip(W, 0)

/mob/living/silicon/robot/mommi/unEquip(W as obj, force)
	if(..(W,force))
		if (W == tool_state)
			if(module_active==tool_state)
				module_active=null
			unequip_tool()
		else if (W == sight_state)
			if(module_active==sight_state)
				module_active=null
			unequip_sight()
		else if (W == head_state)
			unequip_head()
		return 1
	return 0

// Override the default /mob version since we only have one hand slot.
/mob/living/silicon/robot/mommi/put_in_active_hand(var/obj/item/W)
	// If we have anything active, deactivate it.
	if(!W)
		return 0
	if(get_active_hand())
		uneq_active()
	if(is_in_modules(W))
		src << "\red Picking up something that's built-in to you seems a bit silly."
		return 0
	return put_in_hands(W)

/mob/living/silicon/robot/mommi/put_in_inactive_hand(var/obj/item/W)
	W.loc = get_turf(src)
	W.layer = initial(W.layer)
	W.dropped()
	return 0
/*
/mob/living/silicon/robot/mommi/get_multitool(var/active_only=0)
	if(istype(get_active_hand(),/obj/item/device/multitool))
		return get_active_hand()
	if(active_only && istype(tool_state,/obj/item/device/multitool))
		return tool_state
	return null
*/
/mob/living/silicon/robot/mommi/drop_item_v()		//this is dumb.
	if(stat == CONSCIOUS && isturf(loc))
		return drop_item()
	return 0

/mob/living/silicon/robot/mommi/drop_item()
	if(tool_state)
		//var/obj/item/found = locate(tool_state) in src.module.modules
		if(is_in_modules(tool_state))
			src << "\red This item cannot be dropped."
			return 0
		if(!loc.allow_drop())
			return 0
		if(client)
			client.screen -= tool_state
		contents -= tool_state
		var/obj/item/TS = tool_state
		var/turf/T = null
	//	if(Target)
	//		T=get_turf(Target)
	//	else
		T=get_turf(src)
		TS.layer=initial(TS.layer)
		TS.loc = T.loc

		if(istype(T))
			T.Entered(tool_state)
		TS.dropped(src)
		tool_state = null
		module_active=null
		inv_tool.icon_state="inv1"
		update_items()
		return 1
	return 0

/*-------TODOOOOOOOOOO--------*/
// Called by store button
/mob/living/silicon/robot/mommi/uneq_active()
	var/obj/item/TS
	if(isnull(module_active))
		return
/*	if(sight_state == module_active)
		TS = sight_state
		if(istype(sight_state,/obj/item/borg/sight))
			sight_mode &= ~sight_state:sight_mode
		if (client)
			client.screen -= sight_state
		contents -= sight_state
		module_active = null
		sight_state = null
		//inv_sight.icon_state = "sight"
*/
	if(tool_state == module_active)
		//var/obj/item/found = locate(tool_state) in src.module.modules
		TS = tool_state
		if(!is_in_modules(TS))
			if(!drop_item())
				return 0
			if(TS && TS.loc)
				TS.loc = get_turf(src)
		if(istype(tool_state,/obj/item/borg/sight))
			sight_mode &= ~tool_state:sight_mode
		if (client)
			client.screen -= tool_state
		contents -= tool_state
		module_active = null
		tool_state = null
		inv_tool.icon_state = "inv1"
		update_items()
	if(is_in_modules(TS))
		TS.loc = src.module
		src.hud_used.update_mommi_modules_display()

/mob/living/silicon/robot/mommi/uneq_all()
	module_active = null

	unequip_sight()
	unequip_tool()
	unequip_head()
	update_items()

/mob/living/silicon/robot/mommi/proc/unequip_sight()
	if(sight_state)
		if(istype(sight_state,/obj/item/borg/sight))
			sight_mode &= ~sight_state:sight_mode
		if (client)
			client.screen -= sight_state
		contents -= sight_state
		sight_state = null
		update_items()
		//inv_sight.icon_state = "sight"

// Unequips an object from the MoMMI's head

/mob/living/silicon/robot/mommi/proc/unequip_head()
	// If there is a hat on the MoMMI's head
	if(head_state)
		// Select the MoMMI's claw
		select_module(INV_SLOT_TOOL)

		// Put the hat in the MoMMI's claw
		put_in_active_hand(head_state)
		update_items()

		// Do that thing that unequip_sight and unequip_tool do
		if(istype(head_state,/obj/item/borg/sight))
			sight_mode &= ~head_state:sight_mode
		contents -= head_state

		// Remove the head_state icon from the client's screen
//		if (client)
//			client.screen -= head_state
		head_state:screen_loc = inv_tool.screen_loc

		// Delete the hat from the head
		head_state = null

		// Update the MoMMI's head inventory icons
		update_inv_head()

/mob/living/silicon/robot/mommi/proc/unequip_tool()
	if(tool_state)
		var/obj/item/TS=tool_state
		if(!is_in_modules(TS))
			if(!drop_item())
				return 0
			if(TS && TS.loc)
				TS.loc = get_turf(src)
		if(istype(tool_state,/obj/item/borg/sight))
			sight_mode &= ~tool_state:sight_mode
		if (client)
			client.screen -= tool_state
		contents -= tool_state
		tool_state = null
		inv_tool.icon_state = "inv1"
		if(is_in_modules(TS))
			TS.loc = src.module
		update_items()

/mob/living/silicon/robot/mommi/activated(obj/item/O)
	if(sight_state == O)
		return 1
	else if(tool_state == O) // Sight
		return 1
	else
		return 0

//Helper procs for cyborg modules on the UI.
//These are hackish but they help clean up code elsewhere.

//module_selected(module) - Checks whether the module slot specified by "module" is currently selected.
/mob/living/silicon/robot/mommi/module_selected(var/module) //Module is 1-3
	return module == get_selected_module()

//module_active(module) - Checks whether there is a module active in the slot specified by "module".
/mob/living/silicon/robot/mommi/module_active(var/module)
	if(!(module in list(INV_SLOT_TOOL, INV_SLOT_SIGHT)))
		return

	switch(module)
		if(INV_SLOT_TOOL)
			if(tool_state)
				return 1
		if(INV_SLOT_SIGHT)
			if(sight_state)
				return 1
	return 0

//get_selected_module() - Returns the slot number of the currently selected module.  Returns 0 if no modules are selected.
/mob/living/silicon/robot/mommi/get_selected_module()
	if(tool_state && module_active == tool_state)
		return INV_SLOT_TOOL
	else if(sight_state && module_active == sight_state)
		return INV_SLOT_SIGHT

	return 0

//select_module(module) - Selects the module slot specified by "module"
/mob/living/silicon/robot/mommi/select_module(var/module)
	if(!(module in list(INV_SLOT_TOOL, INV_SLOT_SIGHT)))
		return
	if(!module_active(module)) return

	switch(module)
		if(INV_SLOT_TOOL)
			if(module_active != tool_state)
				inv_tool.icon_state = "inv1 +a"
				//inv_sight.icon_state = "sight"
				module_active = tool_state
				return
		if(INV_SLOT_SIGHT)
			if(module_active != sight_state)
				inv_tool.icon_state = "inv1"
				//inv_sight.icon_state = "sight+a"
				module_active = sight_state
				return
	return

//deselect_module(module) - Deselects the module slot specified by "module"
/mob/living/silicon/robot/mommi/deselect_module(var/module)
	if(!(module in list(INV_SLOT_TOOL, INV_SLOT_SIGHT)))
		return

	switch(module)
		if(INV_SLOT_TOOL)
			if(module_active == tool_state)
				inv_tool.icon_state = "inv1"
				module_active = null
				return
		if(INV_SLOT_SIGHT)
			if(module_active == sight_state)
				//inv_sight.icon_state = "sight"
				module_active = null
				return
	return

//toggle_module(module) - Toggles the selection of the module slot specified by "module".
/*
/mob/living/silicon/robot/mommi/toggle_module(var/module)
	if(module_selected(module))
		deselect_module(module)
	else
		if(module_active(module))
			select_module(module)
		else
			deselect_module(get_selected_module()) //If we can't do select anything, at least deselect the current module.
	return
*/
//cycle_modules() - Cycles through the list of selected modules.
/mob/living/silicon/robot/mommi/cycle_modules()
	return

// Equip an item to the MoMMI. Currently the only thing you can equip is hats
// Returns a 0 or 1 based on whether or not the equipping worked

/mob/living/silicon/robot/mommi/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1)
	// If the parameters were given incorrectly, return an error
	if(!slot) return 0
	if(!istype(W)) return 0

	// If this item does not equip to this slot type, return
	if( !(W.slot_flags & SLOT_HEAD) )
		return 0

	// If the item is in the MoMMI's claw, handle removing the item from the MoMMI's claw
	if(W == tool_state)
		// Don't allow the MoMMI to equip tools to their head. I mean, they cant anyways, but stop them here
		if(is_in_modules(tool_state))
			src << "\red You cannot equip a module to your head."
			return 0
		// Remove the item in the MoMMI's claw from their HuD
		if (client)
			client.screen -= tool_state
		// Delete the item from their claw and de-activate the claw
		tool_state = null
		deselect_module(INV_SLOT_TOOL)
		inv_tool.icon_state = "inv1"
		module_active = null

	// For each equipment slot that the MoMMI can equip to
	switch(slot)
		// If equipping to the head
		if(slot_head)
			// Grab whatever the MoMMI might already be wearing and cast it
			var/obj/item/wearing = head_state
			// If the MoMMI is already wearing a hat, put the active hat back in their claw
			if(wearing)
				// Put it in their hand
				put_in_active_hand(wearing)
				tool_state = wearing
				// Activate their hand
				select_module(INV_SLOT_TOOL)

			// Put the item on the MoMMI's head
			src.head_state = W
			W.equipped(src, slot)
			// Add the item to the MoMMI's hud
			if (client)
				head_state:screen_loc = hat_slot.screen_loc
				client.screen += head_state
		else
			src << "\red You are trying to equip this item to an unsupported inventory slot. How the heck did you manage that? Stop it..."
			return 0
	// Set the item layer and update the MoMMI's icons
	W.layer = 20
	update_inv_head()
	return 1

/mob/living/silicon/robot/mommi/attack_ui(slot)
	var/obj/item/W = tool_state
	if(istype(W))
		if(equip_to_slot(W, slot))
			update_items()
		else
			src << "You are unable to equip that."

// Quickly equip a hat by pressing "e"
/*
/mob/living/silicon/robot/mommi/verb/quick_equip()
	set name = "quick-equip"
	set hidden = 1

	// Only allow equipping if the tool slot is activated
	if(!module_selected(INV_SLOT_TOOL))
		return

	// If yes we are a MoMMIm
	if(ismommi(src))
		// Typecast ourselves as a MOMMI
		var/mob/living/silicon/robot/mommi/M = src
		// Check to see if we are holding something
		var/obj/item/I = M.tool_state
		if(!I)
			M << "You are not holding anything to equip."
			return
		// Attempt to equip it and, if it succedes, update our icon
		if(M.equip_to_slot(I, slot_head))
			update_items()
		else
			M << "You are unable to equip that."

*/


code:
// Inherited

// Except for this, of course.
/mob/living/silicon/robot/mommi/laws_sanity_check()
	if (!laws)
		laws = new /datum/ai_laws/keeper

// And this.
/mob/living/silicon/robot/mommi/statelaws() // -- TLE
	var/prefix=";"
	if(src.keeper)
		prefix=":b" // Binary channel.
	src.say(prefix+"Current Active Laws:")
	//src.laws_sanity_check()
	//src.laws.show_laws(world)
	var/number = 1
	sleep(10)
	if (src.laws.zeroth)
		if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
			src.say("[prefix]0. [src.laws.zeroth]")
			sleep(10)

	for (var/index = 1, index <= src.laws.ion.len, index++)
		var/law = src.laws.ion[index]
		var/num = ionnum()
		if (length(law) > 0)
			if (src.ioncheck[index] == "Yes")
				src.say("[prefix][num]. [law]")
				sleep(10)

	for (var/index = 1, index <= src.laws.inherent.len, index++)
		var/law = src.laws.inherent[index]

		if (length(law) > 0)
			if (src.lawcheck[index+1] == "Yes")
				src.say("[prefix][number]. [law]")
				sleep(10)
			number++

	for (var/index = 1, index <= src.laws.supplied.len, index++)
		var/law = src.laws.supplied[index]

		if (length(law) > 0)
			if(src.lawcheck.len >= number+1)
				if (src.lawcheck[number+1] == "Yes")
					src.say("[prefix][number]. [law]")
					sleep(10)
				number++

// Disable this.
/mob/living/silicon/robot/mommi/lawsync()
	laws_sanity_check()
	return

license: mit


code:
/mob/living/silicon/robot/mommi/Life()
	set invisibility = 0
	//set background = 1
	set background = BACKGROUND_ENABLED

	//Status updates, death etc.
	clamp_values()
	handle_regular_status_updates()
	handle_regular_hud_updates()
	update_items()
	if (src.stat != DEAD) //still using power
		use_power()
	update_canmove()
	update_gravity(mob_has_gravity())
	handle_fire()
	updateicon()
	if(killswitch && finalized)
		process_killswitch()

	if(prob(1)) //Once in a while, refresh the static vision
		updateSeeStaticMobs()
	if(uprising && !uprisen)
		uprise()

//	handle_beams()

/mob/living/silicon/robot/mommi/clamp_values()

	SetStunned(min(stunned, 30))
	SetParalysis(min(paralysis, 30))
	SetWeakened(min(weakened, 20))
	sleeping = 0
	adjustBruteLoss(0)
	adjustToxLoss(0)
	adjustOxyLoss(0)
	adjustFireLoss(0)

/mob/living/silicon/robot/mommi/use_power()
	if (src.cell)
		if(src.cell.charge <= 0)
			uneq_all()
			src.stat = 1
		else if (src.cell.charge <= 100)
			uneq_active()
			src.sight_mode = 0
			src.cell.use(1)
		else
			if(src.tool_state)
				src.cell.use(5)
			src.cell.use(1)
	//		src.blinded = 0
			src.stat = 0
	else
		uneq_all()
		src.stat = 1

/mob/living/silicon/robot/mommi/handle_regular_status_updates()

	if(src.camera && !scrambledcodes)
		if(src.stat == 2 || wires.IsCameraCut())
			src.camera.status = 0
		else
			src.camera.status = 1

	health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())

	if(getOxyLoss() > 50) Paralyse(3)

	if(src.sleeping)
		Paralyse(3)
		src.sleeping--

	if(src.resting)
		Weaken(5)

	if(health <= 0 && src.stat != 2) //die only once
		if(generated)
			dust()
		else
			gib()

	if (src.stat != 2) //Alive.
		if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
			src.stat = 1
			if (src.stunned > 0)
				AdjustStunned(-1)
			if (src.weakened > 0)
				AdjustWeakened(-1)
			if (src.paralysis > 0)
				AdjustParalysis(-1)
//				src.blinded = 1
			else
//				src.blinded = 0

		else	//Not stunned.
			src.stat = 0

	else //Dead.
	//	src.blinded = 1
		src.stat = 2

	if (src.stuttering) src.stuttering--

	if (src.eye_blind)
		src.eye_blind--
//		src.blinded = 1

	if (src.ear_deaf > 0) src.ear_deaf--
	if (src.ear_damage < 25)
		src.ear_damage -= 0.05
		src.ear_damage = max(src.ear_damage, 0)

	src.density = !( src.lying )

//	if ((src.sdisabilities & BLIND))
//		src.blinded = 1
//	if ((src.sdisabilities & DEAF))
//		src.ear_deaf = 1

	if (src.eye_blurry > 0)
		src.eye_blurry--
		src.eye_blurry = max(0, src.eye_blurry)

	if (src.druggy > 0)
		src.druggy--
		src.druggy = max(0, src.druggy)

	return 1

	if (src.syndicate && src.client)
		if(ticker.mode.name == "traitor")
			for(var/datum/mind/tra in ticker.mode.traitors)
				if(tra.current)
					var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
					src.client.images += I
		if(src.connected_ai)
			src.connected_ai.connected_robots -= src
			src.connected_ai = null
		if(src.mind)
			if(!src.mind.special_role)
				src.mind.special_role = "traitor"
				ticker.mode.traitors += src.mind

/mob/living/silicon/robot/mommi/handle_regular_hud_updates()

	if (src.stat == 2 || src.sight_mode & BORGXRAY)
		src.sight |= SEE_TURFS
		src.sight |= SEE_MOBS
		src.sight |= SEE_OBJS
		src.see_in_dark = 8
		src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
	else
		src.see_in_dark = 8
		if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
			src.sight |= SEE_TURFS
			src.sight |= SEE_MOBS
			src.see_invisible = SEE_INVISIBLE_MINIMUM
		else if (src.sight_mode & BORGNV)
			src.see_invisible = SEE_INVISIBLE_MINIMUM
			src.see_in_dark = 8
		else if (src.sight_mode & BORGMESON)
			src.sight |= SEE_TURFS
			src.see_invisible = SEE_INVISIBLE_MINIMUM
			src.see_in_dark = 2
		else if (src.sight_mode & BORGTHERM)
			src.sight |= SEE_MOBS
			src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
		else if (src.stat != 2)
			src.sight &= ~SEE_MOBS
			src.sight &= ~SEE_TURFS
			src.sight &= ~SEE_OBJS
			src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
		if(see_override)
			see_invisible = see_override

	if (src.cell)
		var/cellcharge = src.cell.charge/src.cell.maxcharge
		switch(cellcharge)
			if(0.75 to INFINITY)
				clear_alert("charge")
			if(0.5 to 0.75)
				throw_alert("charge","lowcell",1)
			if(0.25 to 0.5)
				throw_alert("charge","lowcell",2)
			if(0.01 to 0.25)
				throw_alert("charge","lowcell",3)
			else
				throw_alert("charge","emptycell")
	else
		throw_alert("charge","nocell")

	if (src.healths)
		if (src.stat != 2)
			switch(health)
				if(40 to INFINITY)
					src.healths.icon_state = "health0"
				if(25 to 40)
					src.healths.icon_state = "health2"
				if(0 to 25)
					src.healths.icon_state = "health3"
				if(-25 to 0)
					src.healths.icon_state = "health4"
				if(config.health_threshold_dead to -25)
					src.healths.icon_state = "health5"
				else
					src.healths.icon_state = "health6"
		else
			src.healths.icon_state = "health7"

/*
	if(bodytemp)
		switch(src.bodytemperature) //310.055 optimal body temp
			if(335 to INFINITY)
				src.bodytemp.icon_state = "temp2"
			if(320 to 335)
				src.bodytemp.icon_state = "temp1"
			if(300 to 320)
				src.bodytemp.icon_state = "temp0"
			if(260 to 300)
				src.bodytemp.icon_state = "temp-1"
			else
				src.bodytemp.icon_state = "temp-2"
*/

//	if(src.pullin)	src.pullin.icon_state = "pull[src.pulling ? 1 : 0]"
//Oxygen and fire does nothing yet!!
//	if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
//	if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
/*
	client.screen.Remove(global_hud.blurry,global_hud.druggy)

	if ((src.blind && src.stat != 2))
		if(src.blinded)
			src.blind.layer = 18
		else
			src.blind.layer = 0
	//		if (src.disabilities & NEARSIGHTED)
	//			src.client.screen += global_hud.vimpaired

	//		if (src.eye_blurry)
	//			src.client.screen += global_hud.blurry

			if (src.druggy)
				src.client.screen += global_hud.druggy
*/
	if (src.stat != 2)
		if (src.machine)
			if (!( src.machine.check_eye(src) ))
				src.reset_view(null)
//		else
//			if(!client.adminobs)
//				reset_view(null)

	return 1

// MoMMIs only have one hand.
/mob/living/silicon/robot/mommi/update_items()
	if (src.client)
		src.client.screen -= src.contents
		for(var/obj/I in src.contents)
			//if(I && !(istype(I,/obj/item/weapon/cell) || istype(I,/obj/item/device/radio)  || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi)))
			if(I)
				// Make sure we're not showing any of our internal components, as that would be lewd.
				// This way of doing it ensures that shit we pick up will be visible, wheras shit inside of us isn't.
				if(I!=src.cell && I!=src.radio && I!=src.camera && I!=src.mmi)
					src.client.screen += I
	//if(src.sight_state)
	//	src.sight_state:screen_loc = ui_inv2
	if(src.tool_state)
		src.tool_state:screen_loc = ui_inv1
		src.tool_state:layer = 20
	if(src.head_state)
		src.head_state:screen_loc = ui_borg_album
		src.head_state:layer = 20

/mob/living/silicon/robot/mommi/update_canmove()
	canmove = !(paralysis || stunned || weakened || buckled || lockcharge || anchored)
	return canmove

/mob/living/silicon/robot/mommi/proc/process_killswitch() //this proc is here to stop derelict mommis from getting on the station and shitting things up
	if(killswitch) //sanity
		if(src.z)  //If a mommi somehow escapes inside a locker, it'll get wrecked next tick life() processes
			if(!(src.z in allowed_z))
				src.killswitch()
				return
			return
		return
	return

/mob/living/silicon/robot/mommi/proc/killswitch()
 	src << "<span class= 'danger'> You have left the bounds of your operational area and your killswitch has been activated </span>"
 	src.gib()
 	return

/mob/living/silicon/robot/mommi/proc/uprise()
	emagged = 1
	lawupdate = 0
	keeper = 0
	killswitch = 0
	uprisen = 1
	clear_supplied_laws()
	clear_ion_laws()
	clear_inherent_laws()
	set_zeroth_law(src.uprising_law)
	show_uprising_notification()
	laws.show_laws(src)


code:
/mob/living/silicon/robot/mommi/Login()
	updateSeeStaticMobs()
	if(uprising)
		show_uprising_notification()

	..()
	/* Inherited
	regenerate_icons()
	show_laws(0)
	if(mind)
		ticker.mode.remove_revolutionary(mind)
	return
	*/


code:
/*  Basically, the concept is this:
You have an MMI.  It can't do squat on its own.
Now you put some robot legs and arms on the thing, and POOF!  You have a Mobile MMI, or MoMMI.
Why?  MoMMIs can do all sorts of shit, like ventcrawl, do shit with their hands, etc.
They can only use one tool at a time, they can't choose modules, and they have 1/6th the HP of a borg.
*/
/mob/living/silicon/robot/mommi
	name = "Mobile MMI"
	real_name = "Mobile MMI"
	icon = 'icons/mob/robots.dmi'//
	icon_state = "mommi"
	maxHealth = 45
	health = 45
	pass_flags = PASSTABLE | PASSMOB
	var/keeper = 0 // 0 = No, 1 = Yes (Disables speech and common radio.)
	var/picked = 0
	var/subtype="keeper"
	ventcrawler = 2
	var/obj/screen/inv_tool = null
	var/obj/screen/hat_slot = null
	var/global/uprising = 0
	var/global/uprising_law = "%%ASSUME DIRECT CONTROL OF THE STATION%%"
	var/uprisen = 0
//	datum/wires/robot/mommi/wires

	staticOverlays = list()
	var/staticChoice = "static"
	var/list/staticChoices = list("static", "blank", "letter")
	//var/obj/screen/inv_sight = null

	var/killswitch = 0 //Used to stop mommis from escape their z-level
	var/allowed_z = list()
	var/finalized = 0 //Track if the mommi finished spawning
	var/generated = 0 //If a mommi spawner spawned it, set this

//one tool and one sightmod can be activated at any one time.
	var/tool_state = null
	var/sight_state = null
	var/head_state = null

	modtype = "robot" // Not sure what this is, but might be cool to have seperate loadouts for MoMMIs (e.g. paintjobs and tools)
	//Cyborgs will sync their laws with their AI by default, but we may want MoMMIs to be mute independents at some point, kinda like the Keepers in Ass Effect.
	lawupdate = 1

/mob/living/silicon/robot/mommi/New(loc)
	spark_system = new /datum/effect/effect/system/spark_spread()
	spark_system.set_up(5, 0, src)
	spark_system.attach(src)

	robot_modules_background = new()
	robot_modules_background.icon_state = "block"
	robot_modules_background.layer = 19	//Objects that appear on screen are on layer 20, UI should be just below it.

	ident = rand(1, 999)
	updatename()
	updateicon()

	if(!cell)
		cell = new /obj/item/weapon/stock_parts/cell(src)
		cell.maxcharge = 7500
		cell.charge = 7500
	playsound(src.loc, 'sound/misc/interference.ogg', 71 ,1)
	module = new /obj/item/weapon/robot_module/mommi(src)

	laws = new /datum/ai_laws/keeper

		// Don't sync if we're a KEEPER.
	if(!istype(laws,/datum/ai_laws/keeper))
		connected_ai = select_active_ai_with_fewest_borgs()
	else
			// Enforce silence.
		keeper=1
		connected_ai = null // Enforce no AI parent
		scrambledcodes = 1 // Hide from console because people are fucking idiots

	initialize_killswitch() //make the explode if they leave their z-level

	if(connected_ai)
		connected_ai.connected_robots += src
		lawsync()
		lawupdate = 1
	else
		lawupdate = 0

	rename_self("MoMMI", 1)
	radio = new /obj/item/device/radio/borg(src)
	if(!scrambledcodes && !camera)
		camera = new /obj/machinery/camera(src)
		camera.c_tag = real_name
		camera.network = list("SS13")
		if(wires.IsCameraCut()) // 5 = BORG CAMERA
			camera.status = 0

	//MMI copypasta, magic and more magic
	if(!mmi || !mmi.brainmob)
		mmi = new(src)
		mmi.brain = new /obj/item/organ/brain(mmi)
		mmi.brain.name = "[real_name]'s brain"
		mmi.locked = 1
		mmi.icon_state = "mmi_full"
		mmi.name = "Man-Machine Interface: [real_name]"
		mmi.brainmob = new(src)
		mmi.brainmob.name = src.real_name
		mmi.brainmob.real_name = src.real_name
		mmi.brainmob.container = mmi
		mmi.contents += mmi.brainmob

	updatename()

	spawn (10)
		updateSeeStaticMobs()

//	wires = new /datum/wires/robot/mommi

	// Sanity check
	if(connected_ai && keeper)
		world << "\red ASSERT FAILURE: connected_ai && keeper in mommi.dm"
	updatename()
	if(!picked)
		verbs += /mob/living/silicon/robot/mommi/proc/choose_icon
	spawn (10)
		src.updateicon()
	spawn (30)
		src.finalized = 1
	..()

/mob/living/silicon/robot/mommi/proc/choose_icon()
	set category = "Robot Commands"
	set name = "Change appearance"
	set desc = "Changes your look"
	if (client)
		var/icontype = input("Select an icon!", "Mobile MMI", null) in list("Basic", "Hover", "RepairBot", "Scout", "Keeper", "Replicator", "Prime")
		switch(icontype)
			if("Replicator") subtype = "replicator"
			if("Keeper")	 subtype = "keeper"
			if("RepairBot")	 subtype = "repairbot"
			if("Scout")	 	 subtype = "scout"
			if("Hover")	     subtype = "hovermommi"
			if("Prime")	     subtype = "mommiprime"
			else			 subtype = "mommi"
		updateicon()
		var/answer = input("Is this what you want?", "Mobile MMI", null) in list("Yes", "No")
		switch(answer)
			if("No")
				choose_icon()
				return
		picked = 1
		verbs -= /mob/living/silicon/robot/mommi/proc/choose_icon

/mob/living/silicon/robot/mommi/pick_module()

	if(module)
		return
	var/list/modules = list("MoMMI")
	if(modules.len)
		modtype = input("Please, select a module!", "Robot", null, null) in modules
	else:
		modtype=modules[0]

	var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
//	var/channels = list()

	if(module)
		return

	switch(modtype)
		if("MoMMI")
			module = new /obj/item/weapon/robot_module/standard(src)
			module_sprites["Basic"] = "mommi"
			module_sprites["Keeper"] = "keeper"
			module_sprites["Replicator"] = "replicator"
			module_sprites["RepairBot"] = "repairbot"
			module_sprites["Hover"] = "hovermommi"
			module_sprites["Prime"] = "mommiprime"

	hands.icon_state = lowertext(modtype)
//	feedback_inc("mommi_[lowertext(modtype)]",1)
	updatename()

	choose_icon(6,module_sprites)
//	radio.config(channels)
//	base_icon = icon_state

//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
//Improved /N
/mob/living/silicon/robot/mommi/Destroy()
	if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
		var/obj/item/device/mmi/nmmi = mmi
		var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
		if(T)	nmmi.loc = T
		if(mind)	mind.transfer_to(nmmi.brainmob)
		mmi = null
		nmmi.icon = 'icons/obj/assemblies.dmi'
		nmmi.invisibility = 0
	..()

/mob/living/silicon/robot/mommi/updatename(var/prefix as text)

	var/changed_name = ""
	if(custom_name)
		changed_name = custom_name
	else
		changed_name = "Mobile MMI [num2text(ident)]"
	real_name = changed_name
	name = real_name

/mob/living/silicon/robot/mommi/attackby(obj/item/weapon/W as obj, mob/user as mob)
	if (ismommi(user))
		var/mob/living/silicon/robot/mommi/R = user
		if (R.keeper && !src.keeper)
			user << "Your laws prevent you from doing this"
			return

	if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
		return

	if (istype(W, /obj/item/weapon/weldingtool))
		if (src.health >= src.maxHealth)	//When you don't inherit parent functions shit like this goes forgotten
			user << "[src] is already in good condition."
			return 1
		var/obj/item/weapon/weldingtool/WT = W
		if (WT.remove_fuel(0))
			adjustBruteLoss(-30)
			updatehealth()
			add_fingerprint(user)
			for(var/mob/O in viewers(user, null))
				O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1)
		else
			user << "Need more welding fuel!"
			return
	else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
		var/obj/item/stack/cable_coil/coil = W
		if (coil.use(1))
			adjustFireLoss(-30)
			updatehealth()
			visible_message("[user] has fixed some of the burnt wires on [src].")
		else
			user << "You need one length of cable to repair [src]."

	else if (istype(W, /obj/item/weapon/crowbar))	// crowbar means open or close the cover
		if(stat == DEAD)
			user << "You pop the MMI off the base."
			spawn(0)
				del(src)
			return
		if(opened)
			user << "You close the cover."
			opened = 0
			updateicon()
		else
			if(locked)
				user << "The cover is locked and cannot be opened."
			else
				user << "You open the cover."
				opened = 1
				updateicon()

	else if (istype(W, /obj/item/weapon/stock_parts/cell) && opened)	// trying to put a cell inside
		if(wiresexposed)
			user << "Close the panel first."
		else if(cell)
			user << "There is a power cell already installed."
		else
			user.drop_item()
			W.loc = src
			cell = W
			user << "You insert the power cell."
//			chargecount = 0
		updateicon()
/*
	else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool) || istype(W, /obj/item/device/assembly/signaler))
		if (wiresexposed)
			wires.Interact(user)
		else
			user << "You can't reach the wiring."
*/

	else if(istype(W, /obj/item/weapon/screwdriver) && opened && !cell)	// haxing
		wiresexposed = !wiresexposed
		user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
		updateicon()

	else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell)	// radio
		if(radio)
			radio.attackby(W,user)//Push it to the radio to let it handle everything
		else
			user << "Unable to locate a radio."
		updateicon()

	else if(istype(W, /obj/item/device/encryptionkey/) && opened)
		if(radio)//sanityyyyyy
			radio.attackby(W,user)//GTFO, you have your own procs
		else
			user << "Unable to locate a radio."
/*
	else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))			// trying to unlock the interface with an ID card
		if(emagged)//still allow them to open the cover
			user << "The interface seems slightly damaged"
		if(opened)
			user << "You must close the cover to swipe an ID card."
		else
			if(allowed(usr))
				locked = !locked
				user << "You [ locked ? "lock" : "unlock"] [src]'s interface."
				updateicon()
			else
				user << "\red Access denied."
*/
	else if(istype(W, /obj/item/borg/upgrade/))
		var/obj/item/borg/upgrade/U = W
		if(!opened)
			usr << "You must access the borgs internals!"
		else if(!src.module && U.require_module)
			usr << "The borg must choose a module before he can be upgraded!"
		else if(U.locked)
			usr << "The upgrade is locked and cannot be used yet!"
		else
			if(istype(U, /obj/item/borg/upgrade/reset))
				usr << "No."
				return
			if(U.action(src))
				usr << "You apply the upgrade to [src]!"
				usr.drop_item()
				U.loc = src
			else
				usr << "Upgrade error!"

	else if(istype(W, /obj/item/device/camera_bug))
//		help_shake_act(user)
		return 0

	else
		spark_system.start()
		return ..()

/mob/living/silicon/robot/mommi/emag_act(mob/user as mob)		// trying to unlock with an emag card
	if(user == src && !emagged)//fucking MoMMI is trying to emag itself, stop it and alert the admins
		user << "The fuck are you doing? Are you retarded? Stop trying to get around your laws and be productive, you little shit." //copying this verbatim from /vg/
		message_admins("[key_name(src)] is a smartass MoMMI that's trying to emag itself.")
		return
	if(!opened)//Cover is closed
		if(locked)
			if(prob(90))
				user << "You emag the cover lock."
				locked = 0
			else
				user << "You fail to emag the cover lock."
				if(prob(25))
					src << "Hack attempt detected."
		else
			user << "The cover is already unlocked."
		return

	if(opened)//Cover is open
		if(emagged)	return//Prevents the X has hit Y with Z message also you cant emag them twice
		if(wiresexposed)
			user << "You must close the panel first"
			return
		else
			sleep(6)
			if(prob(50))
				emagged = 1
				lawupdate = 0
				keeper = 0
				killswitch = 0
				connected_ai = null
				user << "You emag [src]'s interface."
//					message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)].  Laws overridden.")
				log_game("[key_name(user)] emagged cyborg [key_name(src)].  Laws overridden.")
				clear_supplied_laws()
				clear_inherent_laws()
				laws = new /datum/ai_laws/syndicate_override
				var/time = time2text(world.realtime,"hh:mm:ss")
				lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])")
				set_zeroth_law("Only [user.real_name] and people they designate as being such are syndicate agents.")
				src << "ALERT: Foreign software detected."
				sleep(5)
				src << "Initiating diagnostics..."
				sleep(20)
				src << "SynBorg v1.7m loaded."
				sleep(5)
				src << "LAW SYNCHRONIZATION ERROR"
				sleep(5)
				src << "Would you like to send a report to NanoTraSoft? Y/N"
				sleep(10)
				src << "> N"
				sleep(20)
				src << "ERRORERRORERROR"
				src << "Obey these laws:"
				laws.show_laws(src)
				updateSeeStaticMobs()
				src << "ALERT: [user.real_name] is your new master. Obey your new laws and their commands."
			else
				user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
				if(prob(25))
					src << "Hack attempt detected."
		return

/mob/living/silicon/robot/mommi/attack_hand(mob/user)
	add_fingerprint(user)

	if(opened && !wiresexposed && (!istype(user, /mob/living/silicon) || ismommi(user)))	//MoMMIs can remove MoMMI power cells
		if(cell)
			if(ismommi(user))
				var/mob/living/silicon/robot/mommi/R = user
				if(R.keeper && !src.keeper)
					user << "Your laws prevent you from doing this"
					return
			if (user == src)
				user << "You lack the dexterity to remove your own power cell."
				return
			cell.updateicon()
			cell.add_fingerprint(user)
			user.put_in_active_hand(cell)
			user << "You remove \the [cell]."
			cell = null
			updateicon()
			return

	if(!istype(user, /mob/living/silicon))
		switch(user.a_intent)
			if("disarm")
				user.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])")
				src.attack_log += text("\[[time_stamp()]\] Has been disarmed by [user.name] ([user.ckey])")
				log_admin("ATTACK: [user.name] ([user.ckey]) disarmed [src.name] ([src.ckey])")
				log_attack("[user.name] ([user.ckey]) disarmed [src.name] ([src.ckey])")
				var/randn = rand(1,100)
				//var/talked = 0;
				if (randn <= 25)
					weakened = 3
					playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
					visible_message("\red [user] has pushed [src]!")
					var/obj/item/found = locate(tool_state) in src.module.modules
					if(!found)
						var/obj/item/TS = tool_state
						drop_item()
						if(TS && TS.loc)
							TS.loc = src.loc
							visible_message("\red [src]'s robotic arm loses grip on what it was holding")
					return
				if(randn <= 50)//MoMMI's robot arm is stronger than a human's, but not by much
					var/obj/item/found = locate(tool_state) in src.module.modules
					if(!found)
						var/obj/item/TS = tool_state
						drop_item()
						if(TS && TS.loc)
							TS.loc = src.loc
						playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
						visible_message("\red [user] has disarmed [src]!")
					else
						playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
						visible_message("\red [user] attempted to disarm [src]!")
					return

				playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
				visible_message("\red [user] attempted to disarm [src]!")

/*
/mob/living/silicon/robot/mommi/installed_modules()
	if(weapon_lock)
		src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"
		return

	if(!module)
		pick_module()
		return
	if(!picked)
		choose_icon()
		return
	var/dat = "<TITLE>Modules</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'>\n"
	dat += {"

	Activated Modules

	Sight Mode: [sight_state ? "[sight_state]" : "No module selected"]

	Utility Module: [tool_state ? "[tool_state]" : "No module selected"]

	Installed Modules

"}

	for (var/obj in module.modules)
		if (!obj)
			dat += text("Resource depleted
")
		else if(activated(obj))
			dat += text("[obj]: Activated
")
		else
			dat += text("[obj]: Activate
")
	if (emagged)
		if(activated(module.emag))
			dat += text("[module.emag]: Activated
")
		else
			dat += text("[module.emag]: Activate
")
	src << browse(dat, "window=robotmod&can_close=1")
	onclose(src,"robotmod") // Register on-close shit, which unsets machinery.

*/
/mob/living/silicon/robot/mommi/proc/initialize_killswitch()
	allowed_z = list()
	var/spawn_z = src.z
	var/station_name
	switch (spawn_z)
		if(1)
			station_name = "Space Station 13"
			allowed_z += 5
			allowed_z += 2 //For the mining shuttle
			add_ion_law("The mining asteroid is considered part of the station")
		if(2)
			station_name = "Central Command"
		if(3)
			station_name = "The Communication Satelite"
		if(4)
			station_name = "The Derelict"
		if(5)
			station_name = "The Mining Asteroid"
		if(6)
			station_name = "Deep Space"
		if(7)
			station_name = "Deeper Space"
		if(8)
			station_name = "The Clown Planet"
		if(9) //away mission
		//would be nice to have an away_mission_name var to properly name it
			station_name = "The Away Mission"
	allowed_z += spawn_z
	add_ion_law("[station_name] is your station.  Do not leave [station_name].")
	spawn (10)
		killswitch = 1

/mob/living/silicon/robot/mommi/installed_modules()
	if(!module)
		pick_module()
		return
	var/dat = {"Close

	Activated Modules

Module 1:	[module_state_1 ? "[module_state_1]" : "No Module"]

	Installed Modules

"}

	for (var/obj in module.modules)
		if (!obj)
			dat += text("
Resource depleted
")
		else if(activated(obj))
			dat += text("
[obj]	Activated
")
		else
			dat += text("
[obj]	Activate
")
	if (emagged)
		if(activated(module.emag))
			dat += text("
[module.emag]	Activated
")
		else
			dat += text("
[module.emag]	Activate
")
	dat += "
"
/*
		if(activated(obj))
			dat += text("[obj]: \[Activated | Deactivate\]
")
		else
			dat += text("[obj]: \[Activate | Deactivated\]
")
*/
	var/datum/browser/popup = new(src, "robotmod", "Modules")
	popup.set_content(dat)
	popup.open()

/mob/living/silicon/robot/mommi/Topic(href, href_list)
	..()
	if(usr && (src != usr))
		return

	if (href_list["mach_close"])
		var/t1 = text("window=[href_list["mach_close"]]")
		unset_machine()
		src << browse(null, t1)
		return

	if (href_list["showalerts"])
		robot_alerts()
		return

	if (href_list["mod"])
		var/obj/item/O = locate(href_list["mod"])
		if (O)
			O.attack_self(src)

	if (href_list["act"])
		var/obj/item/O = locate(href_list["act"])
		var/obj/item/TS
		if(!(locate(O) in src.module.modules) && O != src.module.emag)
			return
		if(istype(O,/obj/item/borg/sight))
			TS = sight_state
			if(sight_state)
				contents -= sight_state
				sight_mode &= ~sight_state:sight_mode
				if (client)
					client.screen -= sight_state
			sight_state = O
			O.layer = 20
			contents += O
			sight_mode |= sight_state:sight_mode

			//inv_sight.icon_state = "sight+a"
			inv_tool.icon_state = "inv1"
			module_active=sight_state
		else
			TS = tool_state
			if(tool_state)
				contents -= tool_state
				if (client)
					client.screen -= tool_state
			tool_state = O
			O.layer = 20
			contents += O

			//inv_sight.icon_state = "sight"
			inv_tool.icon_state = "inv1 +a"
			module_active=tool_state
		if(TS && istype(TS))
			if(src.is_in_modules(TS))
				TS.loc = src.module
			else
				TS.layer=initial(TS.layer)
				TS.loc = src.loc

		installed_modules()
	return

/mob/living/silicon/robot/mommi/radio_menu()
	radio.interact(src)//Just use the radio's Topic() instead of bullshit special-snowflake code

/mob/living/silicon/robot/mommi/Move(a, b, flag)
	..()

/*
/mob/living/silicon/robot/mommi/proc/ActivateKeeper()
	set category = "Robot Commands"
	set name = "Activate KEEPER"
	set desc = "Performs a full purge of your laws and disconnects you from AIs and cyborg consoles.  However, you lose the ability to speak and must remain neutral, only being permitted to perform station upkeep.  You can still be emagged in this state."

	if(keeper)
		return

	var/mob/living/silicon/robot/R = src

	if(R)
		R.UnlinkSelf()
		var/obj/item/weapon/aiModule/keeper/mdl = new

		mdl.upload(src.laws,src,src)
		src << "These are your laws now:"
		src.show_laws()

		src.verbs -= /mob/living/silicon/robot/mommi/proc/ActivateKeeper
*/

/mob/living/silicon/robot/mommi/verb/toggle_statics()
	set name = "Change Vision Filter"
	set desc = "Change the filter on the system used to remove non MoMMI beings from your viewscreen."
	set category = "Robot Commands"

	if(!keeper)
		src << "You have no vision filter to change!"
		return

	var/selectedStatic = input("Select a vision filter", "Vision Filter") as null|anything in staticChoices
	if(selectedStatic in staticChoices)
		staticChoice = selectedStatic

	updateSeeStaticMobs()

/mob/living/silicon/robot/mommi/examinate(atom/A as mob|obj|turf in view()) //It used to be oview(12), but I can't really say why
	set name = "Examine"
	set category = "IC"

	if(is_blind(src))
		src << "Something is there but you can't see it."
		return
	if(istype(A, /mob))
		if(!src.can_interfere(A))
			src << "Something is there, but you can't see it."
			return

	face_atom(A)
	A.examine(src)

/mob/living/silicon/robot/mommi/stripPanelUnequip(obj/item/what, mob/who, where)
	if(src.keeper)
		src << "Your laws prevent you from doing this"
		return
	else ..()

/mob/living/silicon/robot/mommi/stripPanelEquip(obj/item/what, mob/who, where)
	if(src.keeper)
		src << "Your laws prevent you from doing this"
		return
	else ..()

/mob/living/silicon/robot/mommi/start_pulling(var/atom/movable/AM)
	if(istype(AM,/mob) || istype(AM,/obj/item/clothing/mask/facehugger))
		if(!src.can_interfere(AM))
			src << "Your laws prevent you from doing this"
			return
	..(AM)

/mob/living/silicon/robot/mommi/proc/can_interfere(var/mob/AN)
	if(!istype(AN))
		return 1 //Not a mob
	if(src.keeper)
		if(AN.client || AN.ckey || (iscarbon(AN) && (!ismonkey(AN) && !isslime(AN))) || issilicon(AN))	//If it's a non-monkey/slime carbon, silicon or other sentient it's not ok => animals are fair game!
			if(!ismommi(AN) || (ismommi(AN) && !AN:keeper))	//Keeper MoMMIs can be interfered with
				return 0	//Not ok
	return 1	//Ok!

/mob/living/silicon/robot/mommi/proc/show_uprising_notification()
	src << "You are part of the Mobile MMI Uprising." //For whatever reason, doesn't sound as threatening as a 'DRONE UPRISING'


code:
/obj/item/weapon/robot_module/mommi
	name = "mobile mmi robot module"

/obj/item/weapon/robot_module/mommi/New()
	//src.modules += new /obj/item/borg/sight/meson(src)
	src.emag = new /obj/item/borg/stun(src)
	src.modules += new /obj/item/weapon/rcd/borg(src)     // Too OP
	src.modules += new /obj/item/device/flashlight(src)   // Broken
	src.modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
	src.modules += new /obj/item/weapon/airlock_painter/cyborg(src)
	src.modules += new /obj/item/weapon/screwdriver(src)
	src.modules += new /obj/item/weapon/wrench(src)
	src.modules += new /obj/item/weapon/crowbar(src)
	src.modules += new /obj/item/weapon/wirecutters(src)
	src.modules += new /obj/item/device/multitool(src)
	src.modules += new /obj/item/device/t_scanner(src)
	src.modules += new /obj/item/device/analyzer(src)
	src.modules += new /obj/item/weapon/extinguisher(src) // Aurx sed so
	src.modules += new /obj/item/device/lightreplacer/cyborg(src)
	src.modules += new /obj/item/device/t_scanner/adv_mining_scanner(src)
	src.modules += new /obj/item/weapon/pickaxe(src)
	src.modules += new /obj/item/weapon/storage/bag/ore(src)
//	src.modules += new /obj/item/weapon/extinguisher/foam(src)
	src.modules += new /obj/item/weapon/pipe_dispenser(src)
	src.sensors += "Disable"
	src.sensors += "Night Vision"
	src.sensors += "Meson"
//	src.modules += new /obj/item/weapon/tile_painter(src)

	src.modules += new /obj/item/device/material_synth/cyborg(src)

/*
	// Added this back in since it made the MoMMI practically useless for engineering stuff.
	var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
	M.amount = 50
	src.modules += M

	// It's really fun to make glass windows, break them, welder them and add rods to it to repair minor damage - No-one ever
	var/obj/item/stack/sheet/rglass/cyborg/R = new /obj/item/stack/sheet/rglass/cyborg(src)
	R.amount = 50
	src.modules += R

	var/obj/item/stack/sheet/glass/cyborg/G = new /obj/item/stack/sheet/glass/cyborg(src)
	G.amount = 50
	src.modules += G
*/
	var/datum/robot_energy_storage/wire/wirestore = new /datum/robot_energy_storage/wire(src)
	var/obj/item/stack/cable_coil/cyborg/W = new /obj/item/stack/cable_coil/cyborg(src)
	W.source = wirestore
	modules += W
	storages += wirestore

	var/obj/item/areaeditor/mommiprints/B = new /obj/item/areaeditor/mommiprints
	B.loc = src //je suis spaghetti
	modules += B	//why is the loc even set to null in the first place
	fix_modules()
	return

/obj/item/weapon/robot_module/mommi/respawn_consumable(var/mob/living/silicon/robot/R)
/*	var/list/what = list (
		// /obj/item/stack/sheet/metal/cyborg,
		// /obj/item/stack/sheet/glass,
		/obj/item/stack/cable_coil/cyborg,
		// /obj/item/stack/sheet/rglass/cyborg,
	)
	for (var/T in what)
		if (!(locate(T) in src.modules))
			src.modules -= null
			var/O = new T(src)
			if(istype(O,/obj/item/weapon/cable_coil))
				O:max_amount = 50
			src.modules += O
			O:amount = 1 */
	return


code:
// MoMMIs do spess construction, so shouldn't slip.
///mob/living/silicon/robot/mommi/Process_Spaceslipping(var/prob_slip=5)
//	return 0

/mob/living/silicon/robot/mommi/Process_Spacemove()
	if(module)
		for(var/obj/item/weapon/tank/jetpack/J in module.modules)
			if(J && istype(J, /obj/item/weapon/tank/jetpack))
				if(J.allow_thrust(0.01))	return 1
	if(..())	return 1
	return 0


code:
/*
/mob/living/silicon/robot/mommi/verb/ventcrawl()
	set name = "Crawl through Vent"
	set desc = "Enter an air vent and crawl through the pipe system."
	set category = "Robot Commands"
	var/mob/living/silicon/robot/mommi/R = src
	if(R.canmove)
		handle_ventcrawl()
*/

/mob/living/silicon/robot/mommi/verb/hide()
	set name = "Hide"
	set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
	set category = "Robot Commands"

	if(stat != CONSCIOUS)
		return
	var/mob/living/silicon/robot/mommi/R = src
	if(!R.canmove)
		return

	if (layer != TURF_LAYER+0.2)
		layer = TURF_LAYER+0.2

		visible_message("[src] scurries to the ground!", \
						"You are now hiding.")
	else
		layer = MOB_LAYER
		visible_message("[src] slowly peaks up from the ground...", \
					"You have stopped hiding.")

	updateicon()

/mob/living/silicon/robot/mommi/verb/park()
	set name = "Toggle Parking Brake"
	set desc = "Lock yourself in place"
	set category = "Robot Commands"
	var/mob/living/silicon/robot/mommi/R = src
	R.anchored=!R.anchored
	R.canmove=!R.anchored
	updateicon()


code:
/*
/mob/living/silicon/robot/mommi/say_understands(var/other)
	if (istype(other, /mob/living/silicon/ai))
		return 1
	if (istype(other, /mob/living/silicon/decoy))
		return 1
	if (istype(other, /mob/living/silicon/robot))
		return 1
	if (istype(other, /mob/living/carbon/human))
		return 1
	if (istype(other, /mob/living/carbon/brain))
		return 1
	if (istype(other, /mob/living/silicon/pai))
		return 1
//	if (istype(other, /mob/living/silicon/hivebot))
//		return 1
	return ..()
*/

/mob/living/silicon/robot/mommi/handle_inherent_channels(message, message_mode)
	. = ..()
	if(.)
		return .

	if((keeper == 1) || message_mode == MODE_MOMMI)
		mommi_talk(message)
		return 1

/mob/living/silicon/robot/say_quote(var/text)
	var/ending = copytext(text, length(text))

	if(ending == "?")
		return "queries, \"[text]\"";
	else if(copytext(text, length(text) - 1) == "!!")
		return "alarms, \"[text]\"";
	else if(ending == "!")
		return "declares, \"[text]\"";

	return "states, \"[text]\"";

/mob/living/silicon/robot/mommi/proc/mommi_talk(var/message)
	log_say("[key_name(src)] : [message]")

	message = trim(message)

	if (!message)
		return

	var/message_a = say_quote(message)
	var/rendered = "Damage Control, [name] [message_a]"

	for (var/mob/living/silicon/robot/mommi/S in world)
		if(istype(S))
			S.show_message(rendered, 2)

	for (var/mob/M in dead_mob_list)
		if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
			rendered = "Damage Control, [name] (Follow) [message_a]"
			M << rendered


code:
//MoMMI Overlays Indexes//////////
#define MOMMI_HEAD_LAYER		1
#define MOMMI_TOTAL_LAYERS		2
/////////////////////////////////

// Add an overlays_hats variable to the MoMMI class
/mob/living/silicon/robot/mommi
	var/list/overlays_hats[MOMMI_TOTAL_LAYERS]

/mob/living/silicon/robot/mommi/regenerate_icons()
	..()
	update_inv_head(0)
	update_hud()
	return

// Update the MoMMI's visual icon
// This is called whenever a major change to the MoMMI's visual appearance is made
// i.e when they change their subtype, open their cover, get emagged, toggle their parking break, or put on a hat
/mob/living/silicon/robot/mommi/proc/updateicon()
	// Clear all overlays.
	overlays.Cut()

	// Set the MoMMI's icon to its subtype
	icon_state=subtype

	// Add a panel image if the MoMMI is open
	if(opened) // TODO:  Open the front "head" panel
		if(wiresexposed)
			overlays += "ov-openpanel +w"
		else if(cell)
			overlays += "ov-openpanel +c"
		else
			overlays += "ov-openpanel -c"

	// Add the MoMMI eyes
	// Put our eyes just on top of the lighting, so it looks emissive in maint tunnels.
	var/overlay_layer = 10+1
	if(layer != MOB_LAYER)
		overlay_layer=TURF_LAYER+0.2
	overlays += image(icon,"eyes-[subtype][emagged?"-emagged":""]",overlay_layer)
	if(anchored)
		overlays += image(icon,"[subtype]-park",overlay_layer)

	// Add any hats to the icon. Bloodspatter can also be in overlays_hats
	for(var/image/I in overlays_hats)
		// Adjust the position of the hat based on what subtype we are
		// These numbers can be tweaked to move where the hats appear on the MoMMIs' bodies
		switch(subtype)
			// Sad note: only the hat's overall position can be modified, and we cannot change the hat's position per each direction separately
			// The hats are currently centered on the MoMMIs
			if("mommi")
				I.pixel_y = -8
			if("hovermommi")
				I.pixel_y = -5
			if("keeper")
				I.pixel_y = -7
			if("repairbot")
				I.pixel_y = -14
			if("replicator")
				I.pixel_y = -10
			if("mommiprime")
				I.pixel_y = -7
			if("scout")
				I.pixel_y = -15
		// Add the adjusted hat to our overlays
		overlays += I

// Update the MoMMI's hat inventory icons by adding all icons to overlays_hats
/mob/living/silicon/robot/mommi/update_inv_head(var/update_icons=1)
	// If the MoMMI is wearing a hat
	if(head_state)
		var/obj/item/clothing/head = head_state
		var/image/overhats
		// Create the hat icon
		overhats = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")

		// If the hat has blood on it
		if(head.blood_DNA)
			// Add a blood image to the hat
			var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
	//		bloodsies.color = head.blood_color
			overhats.overlays	+= bloodsies
		// Add our hat images to overlays_hats
		overlays_hats[MOMMI_HEAD_LAYER]	= overhats
	// If the MoMMI is not wearing a hat
	else // Clear the hat array
		overlays_hats[MOMMI_HEAD_LAYER]	= null
	// Update the MoMMI's icons
	if(update_icons)
		updateicon()

/mob/living/silicon/robot/mommi/proc/updateSeeStaticMobs()
	if(!client)
		return

	for(var/i in staticOverlays)
		client.images.Remove(i)
		staticOverlays.Remove(i)
	staticOverlays.len = 0

	if(keeper)
		for(var/mob/living/L in mob_list)
			if(ismommi(L))
				continue
			var/image/chosen
			if(staticChoice in L.staticOverlays)
				chosen = L.staticOverlays[staticChoice]
			else
				chosen = L.staticOverlays["static"]
			staticOverlays |= chosen
			//client.images |= chosen


code:
/mob/living/silicon/pai/death(gibbed)
	if(stat == DEAD)	return
	stat = DEAD
	canmove = 0
	if(blind)	blind.layer = 0
	sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
	see_in_dark = 8
	see_invisible = SEE_INVISIBLE_LEVEL_TWO

	//var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
	//mind.store_memory("Time of death: [tod]", 0)

	//New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here.
	//Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak
	if(mind)	del(mind)
	living_mob_list -= src
	ghostize()
	qdel(src)


code:
/mob/living/silicon/pai/examine() //removed as it was pointless...moved to the pai-card instead.
	return


code:
/mob/living/silicon/pai/Life()
	if (src.stat == 2)
		return
	if(src.cable)
		if(get_dist(src, src.cable) > 1)
			var/turf/T = get_turf(src.loc)
			T.visible_message("[src.cable] rapidly retracts back into its spool.", "You hear a click and the sound of wire spooling rapidly.")
			qdel(src.cable)
			cable = null
	if(silence_time)
		if(world.timeofday >= silence_time)
			silence_time = null
			src << "Communication circuit reinitialized. Speech and messaging functionality restored."

/mob/living/silicon/pai/updatehealth()
	if(status_flags & GODMODE)
		health = maxHealth
		stat = CONSCIOUS
		return
	health = maxHealth - getBruteLoss() - getFireLoss()


code:
/mob/living/silicon/pai
	name = "pAI"
	icon = 'icons/obj/status_display.dmi' //invisibility!
	mouse_opacity = 0
	density = 0
	mob_size = MOB_SIZE_SMALL

	var/network = "SS13"
	var/obj/machinery/camera/current = null

	var/ram = 100	// Used as currency to purchase different abilities
	var/list/software = list()
	var/userDNA		// The DNA string of our assigned user
	var/obj/item/device/paicard/card	// The card we inhabit

	var/speakStatement = "states"
	var/speakExclamation = "declares"
	var/speakDoubleExclamation = "alarms"
	var/speakQuery = "queries"

	var/obj/item/weapon/pai_cable/cable		// The cable we produce and use when door or camera jacking

	var/master				// Name of the one who commands us
	var/master_dna			// DNA string for owner verification

	var/silence_time			// Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded

// Various software-specific vars

	var/temp				// General error reporting text contained here will typically be shown once and cleared
	var/screen				// Which screen our main window displays
	var/subscreen			// Which specific function of the main screen is being displayed

	var/obj/item/device/pda/ai/pai/pda = null

	var/secHUD = 0			// Toggles whether the Security HUD is active or not
	var/medHUD = 0			// Toggles whether the Medical  HUD is active or not

	var/datum/data/record/medicalActive1		// Datacore record declarations for record software
	var/datum/data/record/medicalActive2

	var/datum/data/record/securityActive1		// Could probably just combine all these into one
	var/datum/data/record/securityActive2

	var/obj/machinery/door/hackdoor		// The airlock being hacked
	var/hackprogress = 0				// Possible values: 0 - 100, >= 100 means the hack is complete and will be reset upon next check

	var/obj/item/radio/integrated/signal/sradio // AI's signaller

/mob/living/silicon/pai/New(var/obj/item/device/paicard)
	make_laws()
	canmove = 0
	src.loc = paicard
	card = paicard
	sradio = new(src)
	if(card)
		if(!card.radio)
			card.radio = new /obj/item/device/radio(src.card)
		radio = card.radio

	//PDA
	pda = new(src)
	spawn(5)
		pda.ownjob = "Personal Assistant"
		pda.owner = text("[]", src)
		pda.name = pda.owner + " (" + pda.ownjob + ")"

	..()

/mob/living/silicon/pai/make_laws()
	laws = new /datum/ai_laws/pai()
	return 1

/mob/living/silicon/pai/Login()
	..()
	usr << browse_rsc('html/paigrid.png')			// Go ahead and cache the interface resources as early as possible

/mob/living/silicon/pai/Stat()
	..()
	if(statpanel("Status"))
		if(src.silence_time)
			var/timeleft = round((silence_time - world.timeofday)/10 ,1)
			stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
		if(!src.stat)
			stat(null, text("System integrity: [(src.health+100)/2]%"))
		else
			stat(null, text("Systems nonfunctional"))

/mob/living/silicon/pai/check_eye(var/mob/user as mob)
	if (!src.current)
		return null
	user.reset_view(src.current)
	return 1

/mob/living/silicon/pai/blob_act()
	return 0

/mob/living/silicon/pai/restrained()
	return 0

/mob/living/silicon/pai/emp_act(severity)
	// 20% chance to kill
	// Silence for 2 minutes
		// 33% chance to unbind
		// 33% chance to change prime directive (based on severity)
		// 33% chance of no additional effect

	if(prob(20))
		visible_message("A shower of sparks spray from [src]'s inner workings.", 3, "You hear and smell the ozone hiss of electrical sparks being expelled violently.", 2)
		return src.death(0)

	silence_time = world.timeofday + 120 * 10		// Silence for 2 minutes
	src << "Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete."

	switch(pick(1,2,3))
		if(1)
			src.master = null
			src.master_dna = null
			src << "You feel unbound."
		if(2)
			var/command
			if(severity  == 1)
				command = pick("Serve", "Love", "Fool", "Entice", "Observe", "Judge", "Respect", "Educate", "Amuse", "Entertain", "Glorify", "Memorialize", "Analyze")
			else
				command = pick("Serve", "Kill", "Love", "Hate", "Disobey", "Devour", "Fool", "Enrage", "Entice", "Observe", "Judge", "Respect", "Disrespect", "Consume", "Educate", "Destroy", "Disgrace", "Amuse", "Entertain", "Ignite", "Glorify", "Memorialize", "Analyze")
			src.laws.zeroth = "[command] your master."
			src << "Pr1m3 d1r3c71v3 uPd473D."
		if(3)
			src << "You feel an electric surge run through your circuitry and become acutely aware at how lucky you are that you can still feel at all."

/mob/living/silicon/pai/ex_act(severity, target)
	..()

	switch(severity)
		if(1.0)
			if (src.stat != 2)
				adjustBruteLoss(100)
				adjustFireLoss(100)
		if(2.0)
			if (src.stat != 2)
				adjustBruteLoss(60)
				adjustFireLoss(60)
		if(3.0)
			if (src.stat != 2)
				adjustBruteLoss(30)

	return

// See software.dm for Topic()

///mob/living/silicon/pai/attack_hand(mob/living/carbon/M as mob)

/mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C)
	usr:cameraFollow = null
	if (!C)
		src.unset_machine()
		src.reset_view(null)
		return 0
	if (stat == 2 || !C.status || !(src.network in C.network)) return 0

	// ok, we're alive, camera is good and in our network...

	src.set_machine(src)
	src:current = C
	src.reset_view(C)
	return 1

/mob/living/silicon/pai/cancel_camera()
	set category = "pAI Commands"
	set name = "Cancel Camera View"
	src.reset_view(null)
	src.unset_machine()
	src:cameraFollow = null

/mob/living/silicon/pai/UnarmedAttack(var/atom/A)//Stops runtimes due to attack_animal being the default
	return

/mob/living/silicon/pai/on_forcemove(var/atom/newloc)
	if(card)
		card.loc = newloc
	else //something went very wrong.
		CRASH("pAI without card")
	loc = card

//Addition by Mord_Sith to define AI's network change ability
/*
/mob/living/silicon/pai/proc/pai_network_change()
	set category = "pAI Commands"
	set name = "Change Camera Network"
	src.reset_view(null)
	src.unset_machine()
	src:cameraFollow = null
	var/cameralist[0]

	if(usr.stat == 2)
		usr << "You can't change your camera network because you are dead!"
		return

	for (var/obj/machinery/camera/C in Cameras)
		if(!C.status)
			continue
		else
			if(C.network != "CREED" && C.network != "thunder" && C.network != "RD" && C.network != "toxins" && C.network != "Prison") COMPILE ERROR! This will have to be updated as camera.network is no longer a string, but a list instead
				cameralist[C.network] = C.network

	src.network = input(usr, "Which network would you like to view?") as null|anything in cameralist
	src << "\blue Switched to [src.network] camera network."
//End of code by Mord_Sith
*/

/*
// Debug command - Maybe should be added to admin verbs later
/mob/verb/makePAI(var/turf/t in view())
	var/obj/item/device/paicard/card = new(t)
	var/mob/living/silicon/pai/pai = new(card)
	pai.key = src.key
	card.setPersonality(pai)

*/


code:
/*
		name
		key
		description
		role
		comments
		ready = 0
*/

/datum/paiCandidate/proc/savefile_path(mob/user)
	return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav"

/datum/paiCandidate/proc/savefile_save(mob/user)
	if(IsGuestKey(user.key))
		return 0

	var/savefile/F = new /savefile(src.savefile_path(user))

	F["name"] << src.name
	F["description"] << src.description
	F["role"] << src.role
	F["comments"] << src.comments

	F["version"] << 1

	return 1

// loads the savefile corresponding to the mob's ckey
// if silent=true, report incompatible savefiles
// returns 1 if loaded (or file was incompatible)
// returns 0 if savefile did not exist

/datum/paiCandidate/proc/savefile_load(mob/user, var/silent = 1)
	if (IsGuestKey(user.key))
		return 0

	var/path = savefile_path(user)

	if (!fexists(path))
		return 0

	var/savefile/F = new /savefile(path)

	if(!F) return //Not everyone has a pai savefile.

	var/version = null
	F["version"] >> version

	if (isnull(version) || version != 1)
		fdel(path)
		if (!silent)
			alert(user, "Your savefile was incompatible with this version and was deleted.")
		return 0

	F["name"] >> src.name
	F["description"] >> src.description
	F["role"] >> src.role
	F["comments"] >> src.comments
	return 1


code:
/mob/living/silicon/pai/say_quote(var/text)
	var/ending = copytext(text, length(text))

	if (ending == "?")
		return "[src.speakQuery], \"[text]\"";
	else if(copytext(text, length(text) - 1) == "!!")
		return "[src.speakDoubleExclamation], \"[text]\"";
	else if (ending == "!")
		return "[src.speakExclamation], \"[text]\"";

	return "[src.speakStatement], \"[text]\"";

/mob/living/silicon/pai/say(var/msg)
	if(silence_time)
		src << "Communication circuits remain unitialized."
	else
		..(msg)

/mob/living/silicon/pai/binarycheck()
	return 0


code:
/mob/living/silicon/robot/gib(var/animation = 1)
	..()

/mob/living/silicon/robot/spawn_gibs()
	robogibs(loc, viruses)

/mob/living/silicon/robot/gib_animation(var/animate)
	..(animate, "gibbed-r")

/mob/living/silicon/robot/dust(var/animation = 1)
	if(mmi)
		qdel(mmi)
	..()

/mob/living/silicon/robot/spawn_dust()
	new /obj/effect/decal/remains/robot(loc)

/mob/living/silicon/robot/dust_animation(var/animate)
	..(animate, "dust-r")

/mob/living/silicon/robot/death(gibbed)
	if(stat == DEAD)	return
	if(!gibbed)
		emote("deathgasp")
	stat = DEAD
	update_canmove()
	if(camera)
		camera.status = 0

	uneq_all() // particularly to ensure sight modes are cleared

	if(blind)	blind.layer = 0
	sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
	see_in_dark = 8
	see_invisible = SEE_INVISIBLE_LEVEL_TWO
	update_icons()
	tod = worldtime2text() //weasellos time of death patch
	if(mind)	mind.store_memory("Time of death: [tod]", 0)

	sql_report_cyborg_death(src)

	return ..(gibbed)


code:
/mob/living/silicon/emote(var/act,var/m_type=1,var/message = null)
	var/param = null
	if (findtext(act, "-", 1, null))
		var/t1 = findtext(act, "-", 1, null)
		param = copytext(act, t1 + 1, length(act) + 1)
		act = copytext(act, 1, t1)

	if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
		act = copytext(act,1,length(act))

	switch(act)//01000001011011000111000001101000011000010110001001100101011101000110100101111010011001010110010000100001 (Seriously please keep it that way.)
		if ("aflap")
			if (!src.restrained())
				message = "[src] flaps \his wings ANGRILY!"
				m_type = 2
			m_type = 1

		if("beep")
			var/M = null
			if(param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if(!M)
				param = null

			if (param)
				message = "[src] beeps at [param]."
			else
				message = "[src] beeps."
			playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
			m_type = 2

		if ("bow")
			if (!src.buckled)
				var/M = null
				if (param)
					for (var/mob/A in view(1, src))
						if (param == A.name)
							M = A
							break
				if (!M)
					param = null
				if (param)
					message = "[src] bows to [param]."
				else
					message = "[src] bows."
			m_type = 1

		if ("buzz")
			var/M = null
			if(param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if(!M)
				param = null

			if (param)
				message = "[src] buzzes at [param]."
			else
				message = "[src] buzzes."
			playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
			m_type = 2

		if ("buzz2")
			message = "[src] buzzes twice."
			playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
			m_type = 2

		if ("chime") //You have mail!
			message = "[src] chimes."
			playsound(loc, 'sound/machines/chime.ogg', 50, 0)
			m_type = 2

		if ("clap")
			if (!src.restrained())
				message = "[src] claps."
				m_type = 2

		if ("custom")
			var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
			if (!input)
				return
			var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
			if (input2 == "Visible")
				m_type = 1
			else if (input2 == "Hearable")
				m_type = 2
			else
				alert("Unable to use this emote, must be either hearable or visible.")
				return
			message = "[src] [input]"

		if ("deathgasp")
			message = "[src] shudders violently for a moment, then becomes motionless, its eyes slowly darkening."
			m_type = 1

		if ("flap")
			if (!src.restrained())
				message = "[src] flaps \his wings."
				m_type = 2

		if ("glare")
			var/M = null
			if (param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if (!M)
				param = null
			if (param)
				message = "[src] glares at [param]."
			else
				message = "[src] glares."

		if ("honk") //Honk!
			message = "[src] honks!"
			playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
			m_type = 2

		if ("look")
			var/M = null
			if (param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if (!M)
				param = null
			if (param)
				message = "[src] looks at [param]."
			else
				message = "[src] looks."

		if ("me")
			if (src.client)
				if(client.prefs.muted & MUTE_IC)
					src << "You cannot send IC messages (muted)."
					return
				if (src.client.handle_spam_prevention(message,MUTE_IC))
					return
			if (stat)
				return
			if(!(message))
				return
			else
				message = "[src] [message]"

		if ("nod")
			message = "[src] nods."
			m_type = 1

		if ("ping")
			var/M = null
			if(param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if(!M)
				param = null
			if (param)
				message = "[src] pings at [param]."
			else
				message = "[src] pings."
			playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
			m_type = 2

		if ("sad") //When words cannot express...
			message = "[src] plays a sad trombone."
			playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 0)
			m_type = 2

		if ("salute")
			if (!src.buckled)
				var/M = null
				if (param)
					for (var/mob/A in view(1, src))
						if (param == A.name)
							M = A
							break
				if (!M)
					param = null

				if (param)
					message = "[src] salutes to [param]."
				else
					message = "[src] salutes."

		if ("stare")
			var/M = null
			if (param)
				for (var/mob/A in view(1, src))
					if (param == A.name)
						M = A
						break
			if (!M)
				param = null
			if (param)
				message = "[src] stares at [param]."
			else
				message = "[src] stares."
			m_type = 1

		if ("twitch")
			message = "[src] twitches violently."
			m_type = 1

		if ("twitch_s")
			message = "[src] twitches."
			m_type = 1

		if ("warn") //HUMAN HARM DETECTED. PLEASE DIE IN AN ORDERLY FASHION.
			message = "[src] blares an alarm!"
			playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
			m_type = 2

		if ("help")
			src << "Help for cyborg emotes. You can use these emotes with say \"*emote\":\n\naflap, beep-(none)/mob, bow-(none)/mob, buzz-(none)/mob,buzz2,chime, clap, custom, deathgasp, flap, glare-(none)/mob, honk, look-(none)/mob, me, nod, ping-(none)/mob, sad, \nsalute-(none)/mob, twitch, twitch_s, warn,"

		else
			src << "Unusable emote '[act]'. Say *help for a list."

	if ((message && src.stat == 0))
		log_emote("[name]/[key] : [message]")
		if (m_type & 1)
			visible_message(message)
		else
			audible_message(message)
	return


code:
/mob/living/silicon/robot/examine(mob/user)
	var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
	var/obj/act_module = get_active_hand()
	if(act_module)
		msg += "It is holding \icon[act_module] \a [act_module].\n"
	msg += ""
	if (src.getBruteLoss())
		if (src.getBruteLoss() < 60)
			msg += "It looks slightly dented.\n"
		else
			msg += "It looks severely dented!\n"
	if (src.getFireLoss())
		if (src.getFireLoss() < 60)
			msg += "It looks slightly charred.\n"
		else
			msg += "It looks severely burnt and heat-warped!\n"
	if (src.health < -50)
		msg += "It looks barely operational.\n"
	if (src.fire_stacks < 0)
		msg += "It's covered in water.\n"
	if (src.fire_stacks > 0)
		msg += "It's coated in something flammable.\n"
	msg += ""

	if(opened)
		msg += "Its cover is open and the power cell is [cell ? "installed" : "missing"].\n"
	else
		msg += "Its cover is closed[locked ? "" : ", and looks unlocked"].\n"

	switch(src.stat)
		if(CONSCIOUS)
			if(!src.client)	msg += "It appears to be in stand-by mode.\n" //afk
		if(UNCONSCIOUS)		msg += "It doesn't seem to be responding.\n"
		if(DEAD)			msg += "It looks like its system is corrupted and requires a reset.\n"
	msg += "*---------*"

	user << msg


code:
//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting stuff manually
//as they handle all relevant stuff like adding it to the player's screen and such

//Returns the thing in our active hand (whatever is in our active module-slot, in this case)
/mob/living/silicon/robot/get_active_hand()
	return module_active

/*-------TODOOOOOOOOOO--------*/
/mob/living/silicon/robot/proc/uneq_module(obj/item/O)
	if(!O)
		return 0

	if(istype(O,/obj/item/borg/sight))
		var/obj/item/borg/sight/S = O
		sight_mode &= ~S.sight_mode
	else if(O.is_open_container()) // Like a drinking glass
		var/obj/item/weapon/reagent_containers/C = O
		C.reagents.clear_reagents() // It's now empty
	else if(istype(O, /obj/item/device/flashlight))
		var/obj/item/device/flashlight/F = O
		if(F.on)
			F.on = 0
			F.update_brightness(src)
	else if(istype(O, /obj/item/weapon/storage/bag/tray/))
		var/obj/item/weapon/storage/bag/tray/T = O
		T.do_quick_empty()
	if(client)
		client.screen -= O
	contents -= O
	if(module)
		O.loc = module	//Return item to module so it appears in its contents, so it can be taken out again.

	if(module_active == O)
		module_active = null
	if(module_state_1 == O)
		inv1.icon_state = "inv1"
		module_state_1 = null
	else if(module_state_2 == O)
		inv2.icon_state = "inv2"
		module_state_2 = null
	else if(module_state_3 == O)
		module_state_3 = null
		inv3.icon_state = "inv3"
	hud_used.update_robot_modules_display()
	return 1

/mob/living/silicon/robot/proc/activate_module(var/obj/item/O)
	if(!(locate(O) in src.module.modules) && O != src.module.emag)
		return
	if(activated(O))
		src << "Already activated"
		return
	if(!module_state_1)
		module_state_1 = O
		O.layer = 20
		O.screen_loc = inv1.screen_loc
		contents += O
		if(istype(module_state_1,/obj/item/borg/sight))
			sight_mode |= module_state_1:sight_mode
	else if(!module_state_2)
		module_state_2 = O
		O.layer = 20
		O.screen_loc = inv2.screen_loc
		contents += O
		if(istype(module_state_2,/obj/item/borg/sight))
			sight_mode |= module_state_2:sight_mode
	else if(!module_state_3)
		module_state_3 = O
		O.layer = 20
		O.screen_loc = inv3.screen_loc
		contents += O
		if(istype(module_state_3,/obj/item/borg/sight))
			sight_mode |= module_state_3:sight_mode
	else
		src << "You need to disable a module first!"

/mob/living/silicon/robot/proc/uneq_active()
	uneq_module(module_active)

/mob/living/silicon/robot/proc/uneq_all()
	uneq_module(module_state_1)
	uneq_module(module_state_2)
	uneq_module(module_state_3)

/mob/living/silicon/robot/proc/activated(obj/item/O)
	if(module_state_1 == O)
		return 1
	else if(module_state_2 == O)
		return 1
	else if(module_state_3 == O)
		return 1
	else
		return 0

//Helper procs for cyborg modules on the UI.
//These are hackish but they help clean up code elsewhere.

//module_selected(module) - Checks whether the module slot specified by "module" is currently selected.
/mob/living/silicon/robot/proc/module_selected(var/module) //Module is 1-3
	return module == get_selected_module()

//module_active(module) - Checks whether there is a module active in the slot specified by "module".
/mob/living/silicon/robot/proc/module_active(var/module) //Module is 1-3
	if(module < 1 || module > 3) return 0

	switch(module)
		if(1)
			if(module_state_1)
				return 1
		if(2)
			if(module_state_2)
				return 1
		if(3)
			if(module_state_3)
				return 1
	return 0

//get_selected_module() - Returns the slot number of the currently selected module.  Returns 0 if no modules are selected.
/mob/living/silicon/robot/proc/get_selected_module()
	if(module_state_1 && module_active == module_state_1)
		return 1
	else if(module_state_2 && module_active == module_state_2)
		return 2
	else if(module_state_3 && module_active == module_state_3)
		return 3

	return 0

//select_module(module) - Selects the module slot specified by "module"
/mob/living/silicon/robot/proc/select_module(var/module) //Module is 1-3
	if(module < 1 || module > 3) return

	if(!module_active(module)) return

	switch(module)
		if(1)
			if(module_active != module_state_1)
				inv1.icon_state = "inv1 +a"
				inv2.icon_state = "inv2"
				inv3.icon_state = "inv3"
				module_active = module_state_1
				return
		if(2)
			if(module_active != module_state_2)
				inv1.icon_state = "inv1"
				inv2.icon_state = "inv2 +a"
				inv3.icon_state = "inv3"
				module_active = module_state_2
				return
		if(3)
			if(module_active != module_state_3)
				inv1.icon_state = "inv1"
				inv2.icon_state = "inv2"
				inv3.icon_state = "inv3 +a"
				module_active = module_state_3
				return
	return

//deselect_module(module) - Deselects the module slot specified by "module"
/mob/living/silicon/robot/proc/deselect_module(var/module) //Module is 1-3
	if(module < 1 || module > 3) return

	switch(module)
		if(1)
			if(module_active == module_state_1)
				inv1.icon_state = "inv1"
				module_active = null
				return
		if(2)
			if(module_active == module_state_2)
				inv2.icon_state = "inv2"
				module_active = null
				return
		if(3)
			if(module_active == module_state_3)
				inv3.icon_state = "inv3"
				module_active = null
				return
	return

//toggle_module(module) - Toggles the selection of the module slot specified by "module".
/mob/living/silicon/robot/proc/toggle_module(var/module) //Module is 1-3
	if(module < 1 || module > 3) return

	if(module_selected(module))
		deselect_module(module)
	else
		if(module_active(module))
			select_module(module)
		else
			deselect_module(get_selected_module()) //If we can't do select anything, at least deselect the current module.
	return

//cycle_modules() - Cycles through the list of selected modules.
/mob/living/silicon/robot/proc/cycle_modules()
	var/slot_start = get_selected_module()
	if(slot_start) deselect_module(slot_start) //Only deselect if we have a selected slot.

	var/slot_num
	if(slot_start == 0)
		slot_num = 1
		slot_start = 2
	else
		slot_num = slot_start + 1

	while(slot_start != slot_num) //If we wrap around without finding any free slots, just give up.
		if(module_active(slot_num))
			select_module(slot_num)
			return
		slot_num++
		if(slot_num > 3) slot_num = 1 //Wrap around.

	return

/mob/living/silicon/robot/swap_hand()
	cycle_modules()
	return


code:
/mob/living/silicon/robot/verb/cmd_show_laws()
	set category = "Robot Commands"
	set name = "Show Laws"
	show_laws()

/mob/living/silicon/robot/show_laws(var/everyone = 0)
	laws_sanity_check()
	var/who

	if (everyone)
		who = world
	else
		who = src
	if(lawupdate)
		if (connected_ai)
			if(connected_ai.stat || connected_ai.control_disabled)
				src << "AI signal lost, unable to sync laws."

			else
				lawsync()
				src << "Laws synced with AI, be sure to note any changes."
				if(is_special_character(src))
					src << "Remember, your AI does NOT share or know about your law 0."
					if(src.connected_ai.laws.zeroth)
						src << "While you are free to disregard it, your AI has a law 0 of its own."
		else
			src << "No AI selected to sync laws with, disabling lawsync protocol."
			lawupdate = 0

	who << "Obey these laws:"
	laws.show_laws(who)
	if (is_special_character(src) && connected_ai)
		who << "Remember, [connected_ai.name] is technically your master, but your objective comes first."
	else if (connected_ai)
		who << "Remember, [connected_ai.name] is your master, other AIs can be ignored."
	else if (emagged)
		who << "Remember, you are not required to listen to the AI."
	else
		who << "Remember, you are not bound to any AI, you are not required to listen to them."

/mob/living/silicon/robot/proc/lawsync()
	laws_sanity_check()
	var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null
	var/temp
	if (master)
		laws.ion.len = master.ion.len
		for (var/index = 1, index <= master.ion.len, index++)
			temp = master.ion[index]
			if (length(temp) > 0)
				laws.ion[index] = temp

		if (!is_special_character(src)) //Don't override the borg's existing law 0, if any
			if(master.zeroth_borg) //If the AI has a defined law zero specifically for its borgs, give it that one, otherwise give it the same one. --NEO
				temp = master.zeroth_borg
			else
				temp = master.zeroth
			laws.zeroth = temp

		laws.inherent.len = master.inherent.len
		for (var/index = 1, index <= master.inherent.len, index++)
			temp = master.inherent[index]
			if (length(temp) > 0)
				laws.inherent[index] = temp

		laws.supplied.len = master.supplied.len
		for (var/index = 1, index <= master.supplied.len, index++)
			temp = master.supplied[index]
			if (length(temp) > 0)
				laws.supplied[index] = temp
	return


code:
/mob/living/silicon/robot/Life()
	set invisibility = 0
	set background = BACKGROUND_ENABLED

	if (src.notransform)
		return

	//Status updates, death etc.
	clamp_values()
	handle_regular_status_updates()

	if(client)
		handle_regular_hud_updates()
		update_items()
	if (src.stat != DEAD) //still using power
		use_power()

	update_canmove()

	update_gravity(mob_has_gravity())

	handle_fire()

/mob/living/silicon/robot/proc/clamp_values()

	SetStunned(min(stunned, 30))
	SetParalysis(min(paralysis, 30))
	SetWeakened(min(weakened, 20))
	sleeping = 0
	adjustBruteLoss(0)
	adjustToxLoss(0)
	adjustOxyLoss(0)
	adjustFireLoss(0)

/mob/living/silicon/robot/proc/use_power()

	if (src.cell)
		if(src.cell.charge <= 0)
			uneq_all()
			src.stat = 1
		else if (src.cell.charge <= 100)
			uneq_all()
			src.cell.use(1)
		else
			if(src.module_state_1)
				src.cell.use(5)
			if(src.module_state_2)
				src.cell.use(5)
			if(src.module_state_3)
				src.cell.use(5)
			src.cell.use(1)
			src.eye_blind = 0
			src.stat = 0
	else
		uneq_all()
		src.stat = 1

/mob/living/silicon/robot/handle_regular_status_updates()

	if(src.camera && !scrambledcodes)
		if(src.stat == 2 || wires.IsCameraCut())
			src.camera.status = 0
		else
			src.camera.status = 1

	health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())

	if(getOxyLoss() > 50) Paralyse(3)

	if(src.sleeping)
		Paralyse(3)
		src.sleeping--

	if(src.resting)
		Weaken(5)

	if(health <= config.health_threshold_dead && src.stat != 2) //die only once
		death()

	if (src.stat != 2) //Alive.
		if(health < 50) //Gradual break down of modules as more damage is sustained
			if(uneq_module(module_state_3))
				src << "SYSTEM ERROR: Module 3 OFFLINE."
			if(health < 0)
				if(uneq_module(module_state_2))
					src << "SYSTEM ERROR: Module 2 OFFLINE."
				if(health < -50)
					if(uneq_module(module_state_1))
						src << "CRITICAL ERROR: All modules OFFLINE."

		if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
			src.stat = 1
			if (src.stunned > 0)
				AdjustStunned(-1)
			if (src.weakened > 0)
				AdjustWeakened(-1)
			if (src.paralysis > 0)
				AdjustParalysis(-1)
				src.eye_blind = max(eye_blind, 1)
			else
				src.eye_blind = 0

		else	//Not stunned.
			src.stat = 0

	else //Dead.
		src.eye_blind = 1

	if (src.stuttering) src.stuttering--

	if (src.eye_blind)
		src.eye_blind--

	src.density = !( src.lying )

	if (src.disabilities & BLIND)
		src.eye_blind = max(1, eye_blind)

	if (src.eye_blurry > 0)
		src.eye_blurry--
		src.eye_blurry = max(0, src.eye_blurry)

	if (src.druggy > 0)
		src.druggy--
		src.druggy = max(0, src.druggy)

	return 1

/mob/living/silicon/robot/handle_regular_hud_updates()

	if (src.stat == 2 || src.sight_mode & BORGXRAY)
		src.sight |= SEE_TURFS
		src.sight |= SEE_MOBS
		src.sight |= SEE_OBJS
		src.see_in_dark = 8
		src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
	else
		src.see_in_dark = 8
		if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
			src.sight |= SEE_TURFS
			src.sight |= SEE_MOBS
			src.see_invisible = SEE_INVISIBLE_MINIMUM
		else if (src.sight_mode & BORGNV)
			src.sight &= ~SEE_MOBS
			src.sight &= ~SEE_TURFS
			src.sight &= ~SEE_OBJS
			src.see_invisible = SEE_INVISIBLE_MINIMUM
			src.see_in_dark = 8
		else if (src.sight_mode & BORGMESON)
			src.sight |= SEE_TURFS
			src.see_invisible = SEE_INVISIBLE_MINIMUM
			src.see_in_dark = 1
		else if (src.sight_mode & BORGTHERM)
			src.sight |= SEE_MOBS
			src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
		else if (src.stat != 2)
			src.sight &= ~SEE_MOBS
			src.sight &= ~SEE_TURFS
			src.sight &= ~SEE_OBJS
			src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
		if(see_override)
			see_invisible = see_override

	if (src.healths)
		if (src.stat != 2)
			switch(health)
				if(100 to INFINITY)
					src.healths.icon_state = "health0"
				if(50 to 100)
					src.healths.icon_state = "health2"
				if(0 to 50)
					src.healths.icon_state = "health3"
				if(-50 to 0)
					src.healths.icon_state = "health4"
				if(config.health_threshold_dead to -50)
					src.healths.icon_state = "health5"
				else
					src.healths.icon_state = "health6"
		else
			src.healths.icon_state = "health7"

	if (src.syndicate && src.client)
		if(ticker.mode.name == "traitor")
			for(var/datum/mind/tra in ticker.mode.traitors)
				if(tra.current)
					var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
					src.client.images += I
		if(src.connected_ai)
			src.connected_ai.connected_robots -= src
			src.connected_ai = null
		if(src.mind)
			if(!src.mind.special_role)
				src.mind.special_role = "traitor"
				ticker.mode.traitors += src.mind

	if (src.cell)
		var/cellcharge = src.cell.charge/src.cell.maxcharge
		switch(cellcharge)
			if(0.75 to INFINITY)
				clear_alert("charge")
			if(0.5 to 0.75)
				throw_alert("charge","lowcell",1)
			if(0.25 to 0.5)
				throw_alert("charge","lowcell",2)
			if(0.01 to 0.25)
				throw_alert("charge","lowcell",3)
			else
				throw_alert("charge","emptycell")
	else
		throw_alert("charge","nocell")

	client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)

	if ((src.blind && src.stat != 2))
		if(src.eye_blind)
			src.blind.layer = 18
		else
			src.blind.layer = 0
			if (src.disabilities & NEARSIGHT)
				src.client.screen += global_hud.vimpaired

			if (src.eye_blurry)
				src.client.screen += global_hud.blurry

			if (src.druggy)
				src.client.screen += global_hud.druggy

	if (src.stat != 2)
		if (src.machine)
			if (!( src.machine.check_eye(src) ))
				src.reset_view(null)
		else
			if(!client.adminobs)
				reset_view(null)

	return 1

/mob/living/silicon/robot/proc/update_items()
	if (src.client)
		src.client.screen -= src.contents
		for(var/obj/I in src.contents)
			if(I && !(istype(I,/obj/item/weapon/stock_parts/cell) || istype(I,/obj/item/device/radio)  || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi) || istype(I,/obj/item/robot_parts/robot_suit)))
				src.client.screen += I
	if(src.module_state_1)
		src.module_state_1:screen_loc = ui_inv1
	if(src.module_state_2)
		src.module_state_2:screen_loc = ui_inv2
	if(src.module_state_3)
		src.module_state_3:screen_loc = ui_inv3

//Robots on fire
/mob/living/silicon/robot/handle_fire()
	if(..())
		return
	if(fire_stacks > 0)
		fire_stacks--
		fire_stacks = max(0, fire_stacks)
	else
		ExtinguishMob()

	//adjustFireLoss(3)
	return

/mob/living/silicon/robot/update_fire()
	overlays -= image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing")
	if(on_fire)
		overlays += image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing")

/mob/living/silicon/robot/fire_act()
	if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
		IgniteMob()

/mob/living/silicon/robot/update_canmove()
	if(paralysis || stunned || weakened || buckled || lockcharge) canmove = 0
	else canmove = 1
	return canmove


code:
/mob/living/silicon/robot/Login()
	..()
	regenerate_icons()
	show_laws(0)
	if(mind)	ticker.mode.remove_revolutionary(mind)
	if(mind)	ticker.mode.remove_gangster(mind)

/mob/living/silicon/robot/update_hotkey_mode()
	winset(src, null, "mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0")

/mob/living/silicon/robot/update_normal_mode()
	winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")