text: /obj/item/weapon/robot_module
  	name = "robot module"
  	icon = 'icons/obj/module.dmi'
  	icon_state = "std_module"
  	item_state = "electronic"
  	w_class = ITEM_SIZE_NO_CONTAINER
  	obj_flags = OBJ_FLAG_CONDUCTIBLE
  
  	var/hide_on_manifest = 0
  	var/channels = list()
  	var/networks = list()
  	var/languages = list(
  		LANGUAGE_HUMAN_EURO = TRUE,
  		LANGUAGE_HUMAN_CHINESE = TRUE,
  		LANGUAGE_HUMAN_ARABIC = TRUE,
  		LANGUAGE_HUMAN_INDIAN = TRUE,
  		LANGUAGE_HUMAN_IBERIAN = TRUE,
  		LANGUAGE_HUMAN_RUSSIAN = TRUE,
  		LANGUAGE_HUMAN_SELENIAN = TRUE,
  		LANGUAGE_GUTTER = TRUE,
  		LANGUAGE_LEGALESE = TRUE,
  		LANGUAGE_SPACER = TRUE,
  		LANGUAGE_EAL = TRUE,
  
  		LANGUAGE_UNATHI_SINTA = FALSE,
  		LANGUAGE_SKRELLIAN = FALSE,
  		LANGUAGE_SIGN = FALSE
  		)
  	var/sprites = list()
  	var/can_be_pushed = 1
  	var/no_slip = 0
  	var/obj/item/borg/upgrade/jetpack = null
  	var/list/subsystems = list()
  	var/list/obj/item/borg/upgrade/supported_upgrades = list()
  
  	// Module subsystem category and ID vars.
  	var/display_name
  	var/module_category = ROBOT_MODULE_TYPE_GROUNDED
  	var/crisis_locked =   FALSE
  	var/upgrade_locked =  FALSE
  
  	// Bookkeeping
  	var/list/original_languages = list()
  	var/list/added_networks = list()
  
  	// Gear lists/types.
  	var/obj/item/emag
  	// Please note that due to how locate() works, equipments that are subtypes of other equipment need to be placed after their closest parent
  	var/list/equipment = list()
  	var/list/synths = list()
  	var/list/skills = list() // Skills that this module grants. Other skills will remain at minimum levels.
  
  /obj/item/weapon/robot_module/Initialize()
  
  	. = ..()
  
  	var/mob/living/silicon/robot/R = loc
  	if(!istype(R))
  		return INITIALIZE_HINT_QDEL
  
  	R.module = src
  
  	grant_skills(R)
  	add_camera_networks(R)
  	add_languages(R)
  	add_subsystems(R)
  	apply_status_flags(R)
  
  	if(R.silicon_radio)
  		R.silicon_radio.recalculateChannels()
  
  	build_equipment(R)
  	build_emag(R)
  	build_synths(R)
  
  	finalize_equipment(R)
  	finalize_emag(R)
  	finalize_synths(R)
  
  	R.set_module_sprites(sprites)
  	R.choose_icon(R.module_sprites.len + 1, R.module_sprites)
  
  /obj/item/weapon/robot_module/proc/build_equipment()
  	var/list/created_equipment = list()
  	for(var/thing in equipment)
  		if(ispath(thing, /obj/item))
  			created_equipment |= new thing(src)
  		else if(isitem(thing))
  			var/obj/item/I = thing
  			I.forceMove(src)
  			created_equipment |= I
  		else
  			log_debug("Invalid var type in [type] equipment creation - [thing]")
  	equipment = created_equipment
  
  /obj/item/weapon/robot_module/proc/finalize_equipment()
  	for(var/obj/item/I in equipment)
  		I.canremove = FALSE
  
  /obj/item/weapon/robot_module/proc/build_synths()
  	var/list/created_synths = list()
  	for(var/thing in synths)
  		if(ispath(thing, /datum/matter_synth))
  			if(!isnull(synths[thing]))
  				created_synths += new thing(synths[thing])
  			else
  				created_synths += new thing
  		else if(istype(thing, /datum/matter_synth))
  			created_synths |= thing
  		else
  			log_debug("Invalid var type in [type] synth creation - [thing]")
  	synths = created_synths
  
  /obj/item/weapon/robot_module/proc/finalize_synths()
  	return
  
  /obj/item/weapon/robot_module/proc/build_emag()
  	if(ispath(emag))
  		emag = new emag(src)
  
  /obj/item/weapon/robot_module/proc/finalize_emag()
  	if(istype(emag))
  		emag.canremove = FALSE
  	else
  		log_debug("Invalid var type in [type] emag creation - [emag]")
  		emag = null
  
  /obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
  	remove_camera_networks(R)
  	remove_languages(R)
  	remove_subsystems(R)
  	remove_status_flags(R)
  	reset_skills(R)
  
  	if(R.silicon_radio)
  		R.silicon_radio.recalculateChannels()
  	R.choose_icon(0, R.set_module_sprites(list("Default" = initial(R.icon_state))))
  
  /obj/item/weapon/robot_module/Destroy()
  	QDEL_NULL_LIST(equipment)
  	QDEL_NULL_LIST(synths)
  	QDEL_NULL(emag)
  	QDEL_NULL(jetpack)
  	var/mob/living/silicon/robot/R = loc
  	if(istype(R) && R.module == src)
  		R.module = null
  	. = ..()
  
  /obj/item/weapon/robot_module/emp_act(severity)
  	if(equipment)
  		for(var/obj/O in equipment)
  			O.emp_act(severity)
  	if(emag)
  		emag.emp_act(severity)
  	if(synths)
  		for(var/datum/matter_synth/S in synths)
  			S.emp_act(severity)
  	..()
  
  /obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
  	var/obj/item/device/flash/F = locate() in equipment
  	if(F)
  		if(F.broken)
  			F.broken = 0
  			F.times_used = 0
  			F.icon_state = "flash"
  		else if(F.times_used)
  			F.times_used--
  	if(!synths || !synths.len)
  		return
  	for(var/datum/matter_synth/T in synths)
  		T.add_charge(T.recharge_rate * rate)
  
  /obj/item/weapon/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
  	// Stores the languages as they were before receiving the module, and whether they could be synthezized.
  	for(var/datum/language/language_datum in R.languages)
  		original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs)
  
  	for(var/language in languages)
  		R.add_language(language, languages[language])
  
  /obj/item/weapon/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R)
  	// Clear all added languages, whether or not we originally had them.
  	for(var/language in languages)
  		R.remove_language(language)
  
  	// Then add back all the original languages, and the relevant synthezising ability
  	for(var/original_language in original_languages)
  		var/datum/language/language_datum = original_language
  		R.add_language(language_datum.name, original_languages[original_language])
  	original_languages.Cut()
  
  /obj/item/weapon/robot_module/proc/add_camera_networks(var/mob/living/silicon/robot/R)
  	if(R.camera && (NETWORK_ROBOTS in R.camera.network))
  		for(var/network in networks)
  			if(!(network in R.camera.network))
  				R.camera.add_network(network)
  				added_networks |= network
  
  /obj/item/weapon/robot_module/proc/remove_camera_networks(var/mob/living/silicon/robot/R)
  	if(R.camera)
  		R.camera.remove_networks(added_networks)
  	added_networks.Cut()
  
  /obj/item/weapon/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
  	for(var/subsystem_type in subsystems)
  		R.init_subsystem(subsystem_type)
  
  /obj/item/weapon/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
  	for(var/subsystem_type in subsystems)
  		R.remove_subsystem(subsystem_type)
  
  /obj/item/weapon/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R)
  	if(!can_be_pushed)
  		R.status_flags &= ~CANPUSH
  
  /obj/item/weapon/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/R)
  	if(!can_be_pushed)
  		R.status_flags |= CANPUSH
  
  /obj/item/weapon/robot_module/proc/handle_emagged()
  	return
  
  /obj/item/weapon/robot_module/proc/grant_skills(var/mob/living/silicon/robot/R)
  	reset_skills(R) // for safety
  	var/list/skill_mod = list()
  	for(var/skill_type in skills)
  		skill_mod[skill_type] = skills[skill_type] - SKILL_MIN // the buff is additive, so normalize accordingly
  	R.buff_skill(skill_mod, buff_type = /datum/skill_buff/robot)
  
  /obj/item/weapon/robot_module/proc/reset_skills(var/mob/living/silicon/robot/R)
  	for(var/datum/skill_buff/buff in R.fetch_buffs_of_type(/datum/skill_buff/robot))
  		buff.remove()
  