diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 61df11b48ff..56b042e363a 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -1,421 +1,424 @@
-/mob/living/silicon
- gender = NEUTER
- voice_name = "synthesized voice"
- var/syndicate = 0
- var/const/MAIN_CHANNEL = "Main Frequency"
- var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
- var/list/stating_laws = list()// Channels laws are currently being stated on
- var/obj/item/device/radio/common_radio
-
- has_huds = TRUE
- var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
-
- //Used in say.dm.
- var/speak_statement = "states"
- var/speak_exclamation = "declares"
- var/speak_query = "queries"
- var/pose //Yes, now AIs can pose too.
- var/obj/item/device/camera/siliconcam/aiCamera = null //photography
- var/local_transmit //If set, can only speak to others of the same type within a short range.
-
- var/next_alarm_notice
- var/list/datum/alarm/queued_alarms = new()
-
- var/list/access_rights
- var/obj/item/weapon/card/id/idcard
- var/idcard_type = /obj/item/weapon/card/id/synthetic
-
- var/hudmode = null
-
-/mob/living/silicon/New()
- silicon_mob_list |= src
- ..()
- add_language(LANGUAGE_GALCOM)
- set_default_language(GLOB.all_languages[LANGUAGE_GALCOM])
- init_id()
- init_subsystems()
-
-/mob/living/silicon/Destroy()
- silicon_mob_list -= src
- for(var/datum/alarm_handler/AH in SSalarm.all_handlers)
- AH.unregister_alarm(src)
- return ..()
-
-/mob/living/silicon/proc/init_id()
- if(idcard)
- return
- idcard = new idcard_type(src)
- set_id_info(idcard)
-
-/mob/living/silicon/proc/SetName(pickedName as text)
- real_name = pickedName
- name = real_name
-
-/mob/living/silicon/proc/show_laws()
- return
-
-/mob/living/silicon/drop_item()
- return
-
-/mob/living/silicon/emp_act(severity)
- switch(severity)
- if(1)
- src.take_organ_damage(0,20,emp=1)
- Confuse(5)
- if(2)
- src.take_organ_damage(0,15,emp=1)
- Confuse(4)
- if(3)
- src.take_organ_damage(0,10,emp=1)
- Confuse(3)
- if(4)
- src.take_organ_damage(0,5,emp=1)
- Confuse(2)
- flash_eyes(affect_silicon = 1)
- to_chat(src, "*BZZZT*")
- to_chat(src, "Warning: Electromagnetic pulse detected.")
- ..()
-
-/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount)
- return //immune
-
-/mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 0.0, var/def_zone = null, var/stun = 1)
- if(shock_damage > 0)
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, loc)
- s.start()
-
- shock_damage *= siemens_coeff //take reduced damage
- take_overall_damage(0, shock_damage)
- visible_message("[src] was shocked by \the [source]!", \
- "Energy pulse detected, system damaged!", \
- "You hear an electrical crack.")
- if(prob(20))
- Stun(2)
- return
-
-/mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0)
- return
-
-/mob/living/silicon/IsAdvancedToolUser()
- return 1
-
-/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
-
- if(!Proj.nodamage)
- switch(Proj.damage_type)
- if(BRUTE)
- adjustBruteLoss(Proj.damage)
- if(BURN)
- adjustFireLoss(Proj.damage)
-
- Proj.on_hit(src,2)
- updatehealth()
- return 2
-
-/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
- return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
-
-
-/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
- if(!istype(bot) || !istype(ai))
- return 0
- if (bot.connected_ai == ai)
- return 1
- return 0
-
-
-// this function shows the health of the AI in the Status panel
-/mob/living/silicon/proc/show_system_integrity()
- if(!src.stat)
- stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%"))
- else
- stat(null, text("Systems nonfunctional"))
-
-
-// This is a pure virtual function, it should be overwritten by all subclasses
-/mob/living/silicon/proc/show_malf_ai()
- return 0
-
-// this function displays the shuttles ETA in the status panel if the shuttle has been called
-/mob/living/silicon/proc/show_emergency_shuttle_eta()
- if(emergency_shuttle)
- var/eta_status = emergency_shuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
-
-
-// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
-/mob/living/silicon/Stat()
- if(statpanel("Status"))
- show_emergency_shuttle_eta()
- show_system_integrity()
- show_malf_ai()
- ..()
-
-/* VOREStation Removal
-// this function displays the stations manifest in a separate window
-/mob/living/silicon/proc/show_station_manifest()
- var/dat = "
"
- if(!data_core)
- to_chat(src, "
There is no data to form a manifest with. Contact your Nanotrasen administrator.")
- return
- dat += data_core.get_manifest(1) //The 1 makes it monochrome.
-
- var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src)
- popup.set_content(dat)
- popup.open()
-*/
-
-//can't inject synths
-/mob/living/silicon/can_inject(var/mob/user, var/error_msg, var/target_zone, var/ignore_thickness = FALSE)
- if(error_msg)
- to_chat(user, "
The armoured plating is too tough.")
- return 0
-
-
-//Silicon mob language procs
-
-/mob/living/silicon/can_speak(datum/language/speaking)
- if(universal_speak)
- return TRUE
- //need speech synthesizer support to vocalize a language
- if(speaking in speech_synthesizer_langs)
- return TRUE
- if(speaking && speaking.flags & INNATE)
- return TRUE
- return FALSE
-
-/mob/living/silicon/add_language(var/language, var/can_speak=1)
- var/datum/language/added_language = GLOB.all_languages[language]
- if(!added_language)
- return
-
- . = ..(language)
- if (can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
- speech_synthesizer_langs += added_language
- return 1
-
-/mob/living/silicon/remove_language(var/rem_language)
- var/datum/language/removed_language = GLOB.all_languages[rem_language]
- if(!removed_language)
- return
-
- ..(rem_language)
- speech_synthesizer_langs -= removed_language
-
-/mob/living/silicon/check_lang_data()
- . = ""
-
- if(default_language)
- . += "Current default language: [default_language] -
reset"
-
- for(var/datum/language/L in languages)
- if(!(L.flags & NONGLOBAL))
- var/default_str
- if(L == default_language)
- default_str = " - default -
reset"
- else
- default_str = " -
set default"
-
- var/synth = (L in speech_synthesizer_langs)
- . += "
[L.name] ([get_language_prefix()][L.key])[synth ? default_str : null]
Speech Synthesizer:
[synth ? "YES" : "NOT SUPPORTED"][L.desc]
"
-
-/mob/living/silicon/proc/toggle_sensor_mode()
- var/sensor_type = tgui_input_list(usr, "Please select sensor type.", "Sensor Integration", list("Security","Medical","Disable"))
- switch(sensor_type)
- if ("Security")
- if(plane_holder)
- //Enable Security planes
- plane_holder.set_vis(VIS_CH_ID,TRUE)
- plane_holder.set_vis(VIS_CH_WANTED,TRUE)
- plane_holder.set_vis(VIS_CH_IMPLOYAL,TRUE)
- plane_holder.set_vis(VIS_CH_IMPTRACK,TRUE)
- plane_holder.set_vis(VIS_CH_IMPCHEM,TRUE)
-
- //Disable Medical planes
- plane_holder.set_vis(VIS_CH_STATUS,FALSE)
- plane_holder.set_vis(VIS_CH_HEALTH,FALSE)
-
- to_chat(src, "
Security records overlay enabled.")
- if ("Medical")
- if(plane_holder)
- //Disable Security planes
- plane_holder.set_vis(VIS_CH_ID,FALSE)
- plane_holder.set_vis(VIS_CH_WANTED,FALSE)
- plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE)
- plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE)
- plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE)
-
- //Enable Medical planes
- plane_holder.set_vis(VIS_CH_STATUS,TRUE)
- plane_holder.set_vis(VIS_CH_HEALTH,TRUE)
-
- to_chat(src, "
Life signs monitor overlay enabled.")
- if ("Disable")
- if(plane_holder)
- //Disable Security planes
- plane_holder.set_vis(VIS_CH_ID,FALSE)
- plane_holder.set_vis(VIS_CH_WANTED,FALSE)
- plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE)
- plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE)
- plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE)
-
- //Disable Medical planes
- plane_holder.set_vis(VIS_CH_STATUS,FALSE)
- plane_holder.set_vis(VIS_CH_HEALTH,FALSE)
- to_chat(src, "Sensor augmentations disabled.")
-
- hudmode = sensor_type //This is checked in examine.dm on humans, so they can see medical/security records depending on mode
-
-/mob/living/silicon/verb/pose()
- set name = "Set Pose"
- set desc = "Sets a description which will be shown when someone examines you."
- set category = "IC"
-
- pose = sanitize(input(usr, "This is [src]. It is...", "Pose", null) as text)
-
-/mob/living/silicon/verb/set_flavor()
- set name = "Set Flavour Text"
- set desc = "Sets an extended description of your character's features."
- set category = "IC"
-
- flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
-
-/mob/living/silicon/binarycheck()
- return 1
-
-/mob/living/silicon/ex_act(severity)
- if(!blinded)
- flash_eyes()
-
- for(var/datum/modifier/M in modifiers)
- if(!isnull(M.explosion_modifier))
- severity = CLAMP(severity + M.explosion_modifier, 1, 4)
-
- severity = round(severity)
-
- if(severity > 3)
- return
-
- switch(severity)
- if(1.0)
- if (stat != 2)
- adjustBruteLoss(100)
- adjustFireLoss(100)
- if(!anchored)
- gib()
- if(2.0)
- if (stat != 2)
- adjustBruteLoss(60)
- adjustFireLoss(60)
- if(3.0)
- if (stat != 2)
- adjustBruteLoss(30)
-
- updatehealth()
-
-/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
- if(!next_alarm_notice)
- next_alarm_notice = world.time + SecondsToTicks(10)
- if(alarm.hidden)
- return
- if(alarm.origin && !(get_z(alarm.origin) in using_map.get_map_levels(get_z(src), TRUE, om_range = DEFAULT_OVERMAP_RANGE)))
- return
-
- var/list/alarms = queued_alarms[alarm_handler]
- if(was_raised)
- // Raised alarms are always set
- alarms[alarm] = 1
- else
- // Alarms that were raised but then cleared before the next notice are instead removed
- if(alarm in alarms)
- alarms -= alarm
- // And alarms that have only been cleared thus far are set as such
- else
- alarms[alarm] = -1
-
-/mob/living/silicon/proc/process_queued_alarms()
- if(next_alarm_notice && (world.time > next_alarm_notice))
- next_alarm_notice = 0
-
- var/alarm_raised = 0
- for(var/datum/alarm_handler/AH in queued_alarms)
- var/list/alarms = queued_alarms[AH]
- var/reported = 0
- for(var/datum/alarm/A in alarms)
- if(alarms[A] == 1)
- alarm_raised = 1
- if(!reported)
- reported = 1
- to_chat(src, "
--- [AH.category] Detected ---")
- raised_alarm(A)
-
- for(var/datum/alarm_handler/AH in queued_alarms)
- var/list/alarms = queued_alarms[AH]
- var/reported = 0
- for(var/datum/alarm/A in alarms)
- if(alarms[A] == -1)
- if(!reported)
- reported = 1
- to_chat(src, "
--- [AH.category] Cleared ---")
- to_chat(src, "\The [A.alarm_name()].")
-
- if(alarm_raised)
- to_chat(src, "
\[Show Alerts\]")
-
- for(var/datum/alarm_handler/AH in queued_alarms)
- var/list/alarms = queued_alarms[AH]
- alarms.Cut()
-
-/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
- to_chat(src, "[A.alarm_name()]!")
-
-/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
- var/cameratext = ""
- for(var/obj/machinery/camera/C in A.cameras())
- cameratext += "[(cameratext == "")? "" : "|"]
[C.c_tag]"
- to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
-
-
-/mob/living/silicon/proc/is_traitor()
- return mind && (mind in traitors.current_antagonists)
-
-/mob/living/silicon/proc/is_malf()
- return mind && (mind in malf.current_antagonists)
-
-/mob/living/silicon/proc/is_malf_or_traitor()
- return is_traitor() || is_malf()
-
-/mob/living/silicon/adjustEarDamage()
- return
-
-/mob/living/silicon/setEarDamage()
- return
-
-/mob/living/silicon/reset_view()
- . = ..()
- if(cameraFollow)
- cameraFollow = null
-
-/mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
- if(affect_silicon)
- return ..()
-
-/mob/living/silicon/proc/clear_client()
- //Handle job slot/tater cleanup.
- var/job = mind.assigned_role
-
- job_master.FreeRole(job)
-
- if(mind.objectives.len)
- qdel(mind.objectives)
- mind.special_role = null
-
- clear_antag_roles(mind)
-
- ghostize(0)
- qdel(src)
-
-/mob/living/silicon/has_vision()
- return 0 //NOT REAL EYES
+/mob/living/silicon
+ gender = NEUTER
+ voice_name = "synthesized voice"
+ var/syndicate = 0
+ var/const/MAIN_CHANNEL = "Main Frequency"
+ var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
+ var/list/stating_laws = list()// Channels laws are currently being stated on
+ var/obj/item/device/radio/common_radio
+
+ has_huds = TRUE
+ var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
+
+ //Used in say.dm.
+ var/speak_statement = "states"
+ var/speak_exclamation = "declares"
+ var/speak_query = "queries"
+ var/pose //Yes, now AIs can pose too.
+ var/obj/item/device/camera/siliconcam/aiCamera = null //photography
+ var/local_transmit //If set, can only speak to others of the same type within a short range.
+
+ var/next_alarm_notice
+ var/list/datum/alarm/queued_alarms = new()
+
+ var/list/access_rights
+ var/obj/item/weapon/card/id/idcard
+ var/idcard_type = /obj/item/weapon/card/id/synthetic
+
+ var/hudmode = null
+
+/mob/living/silicon/New()
+ silicon_mob_list |= src
+ ..()
+ add_language(LANGUAGE_GALCOM)
+ set_default_language(GLOB.all_languages[LANGUAGE_GALCOM])
+ init_id()
+ init_subsystems()
+
+/mob/living/silicon/Destroy()
+ silicon_mob_list -= src
+ for(var/datum/alarm_handler/AH in SSalarm.all_handlers)
+ AH.unregister_alarm(src)
+ return ..()
+
+/mob/living/silicon/proc/init_id()
+ if(idcard)
+ return
+ idcard = new idcard_type(src)
+ set_id_info(idcard)
+
+/mob/living/silicon/proc/SetName(pickedName as text)
+ real_name = pickedName
+ name = real_name
+
+/mob/living/silicon/proc/show_laws()
+ return
+
+/mob/living/silicon/drop_item()
+ return
+
+/mob/living/silicon/emp_act(severity)
+ switch(severity)
+ if(1)
+ src.take_organ_damage(0,20,emp=1)
+ Confuse(5)
+ if(2)
+ src.take_organ_damage(0,15,emp=1)
+ Confuse(4)
+ if(3)
+ src.take_organ_damage(0,10,emp=1)
+ Confuse(3)
+ if(4)
+ src.take_organ_damage(0,5,emp=1)
+ Confuse(2)
+ flash_eyes(affect_silicon = 1)
+ to_chat(src, "
*BZZZT*")
+ to_chat(src, "
Warning: Electromagnetic pulse detected.")
+ ..()
+
+/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount)
+ return //immune
+
+/mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 0.0, var/def_zone = null, var/stun = 1)
+ if(shock_damage > 0)
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, loc)
+ s.start()
+
+ shock_damage *= siemens_coeff //take reduced damage
+ take_overall_damage(0, shock_damage)
+ visible_message("
[src] was shocked by \the [source]!", \
+ "
Energy pulse detected, system damaged!", \
+ "
You hear an electrical crack.")
+ if(prob(20))
+ Stun(2)
+ return
+
+/mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0)
+ return
+
+/mob/living/silicon/IsAdvancedToolUser()
+ return 1
+
+/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
+
+ if(!Proj.nodamage)
+ switch(Proj.damage_type)
+ if(BRUTE)
+ adjustBruteLoss(Proj.damage)
+ if(BURN)
+ adjustFireLoss(Proj.damage)
+
+ Proj.on_hit(src,2)
+ updatehealth()
+ return 2
+
+/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
+ return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
+
+
+/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
+ if(!istype(bot) || !istype(ai))
+ return 0
+ if (bot.connected_ai == ai)
+ return 1
+ return 0
+
+
+// this function shows the health of the AI in the Status panel
+/mob/living/silicon/proc/show_system_integrity()
+ if(!src.stat)
+ stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%"))
+ else
+ stat(null, text("Systems nonfunctional"))
+
+
+// This is a pure virtual function, it should be overwritten by all subclasses
+/mob/living/silicon/proc/show_malf_ai()
+ return 0
+
+// this function displays the shuttles ETA in the status panel if the shuttle has been called
+/mob/living/silicon/proc/show_emergency_shuttle_eta()
+ if(emergency_shuttle)
+ var/eta_status = emergency_shuttle.get_status_panel_eta()
+ if(eta_status)
+ stat(null, eta_status)
+
+
+// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
+/mob/living/silicon/Stat()
+ if(statpanel("Status"))
+ show_emergency_shuttle_eta()
+ show_system_integrity()
+ show_malf_ai()
+ ..()
+
+/* VOREStation Removal
+// this function displays the stations manifest in a separate window
+/mob/living/silicon/proc/show_station_manifest()
+ var/dat = "
"
+ if(!data_core)
+ to_chat(src, "
There is no data to form a manifest with. Contact your Nanotrasen administrator.")
+ return
+ dat += data_core.get_manifest(1) //The 1 makes it monochrome.
+
+ var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src)
+ popup.set_content(dat)
+ popup.open()
+*/
+
+//can't inject synths
+/mob/living/silicon/can_inject(var/mob/user, var/error_msg, var/target_zone, var/ignore_thickness = FALSE)
+ if(error_msg)
+ to_chat(user, "
The armoured plating is too tough.")
+ return 0
+
+
+//Silicon mob language procs
+
+/mob/living/silicon/can_speak(datum/language/speaking)
+ if(universal_speak)
+ return TRUE
+ //need speech synthesizer support to vocalize a language
+ if(speaking in speech_synthesizer_langs)
+ return TRUE
+ if(speaking && speaking.flags & INNATE)
+ return TRUE
+ return FALSE
+
+/mob/living/silicon/add_language(var/language, var/can_speak=1)
+ var/datum/language/added_language = GLOB.all_languages[language]
+ if(!added_language)
+ return
+
+ . = ..(language)
+ if (can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
+ speech_synthesizer_langs += added_language
+ return 1
+
+/mob/living/silicon/remove_language(var/rem_language)
+ var/datum/language/removed_language = GLOB.all_languages[rem_language]
+ if(!removed_language)
+ return
+
+ ..(rem_language)
+ speech_synthesizer_langs -= removed_language
+
+/mob/living/silicon/check_lang_data()
+ . = ""
+
+ if(default_language)
+ . += "Current default language: [default_language] -
reset"
+
+ for(var/datum/language/L in languages)
+ if(!(L.flags & NONGLOBAL))
+ var/default_str
+ if(L == default_language)
+ default_str = " - default -
reset"
+ else
+ default_str = " -
set default"
+
+ var/synth = (L in speech_synthesizer_langs)
+ . += "
[L.name] ([get_language_prefix()][L.key])[synth ? default_str : null]
Speech Synthesizer:
[synth ? "YES" : "NOT SUPPORTED"][L.desc]
"
+
+/mob/living/silicon/proc/toggle_sensor_mode()
+ var/sensor_type = tgui_input_list(usr, "Please select sensor type.", "Sensor Integration", list("Security","Medical","Disable"))
+ switch(sensor_type)
+ if ("Security")
+ if(plane_holder)
+ //Enable Security planes
+ plane_holder.set_vis(VIS_CH_ID,TRUE)
+ plane_holder.set_vis(VIS_CH_WANTED,TRUE)
+ plane_holder.set_vis(VIS_CH_IMPLOYAL,TRUE)
+ plane_holder.set_vis(VIS_CH_IMPTRACK,TRUE)
+ plane_holder.set_vis(VIS_CH_IMPCHEM,TRUE)
+
+ //Disable Medical planes
+ plane_holder.set_vis(VIS_CH_STATUS,FALSE)
+ plane_holder.set_vis(VIS_CH_HEALTH,FALSE)
+
+ to_chat(src, "
Security records overlay enabled.")
+ if ("Medical")
+ if(plane_holder)
+ //Disable Security planes
+ plane_holder.set_vis(VIS_CH_ID,FALSE)
+ plane_holder.set_vis(VIS_CH_WANTED,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE)
+
+ //Enable Medical planes
+ plane_holder.set_vis(VIS_CH_STATUS,TRUE)
+ plane_holder.set_vis(VIS_CH_HEALTH,TRUE)
+
+ to_chat(src, "
Life signs monitor overlay enabled.")
+ if ("Disable")
+ if(plane_holder)
+ //Disable Security planes
+ plane_holder.set_vis(VIS_CH_ID,FALSE)
+ plane_holder.set_vis(VIS_CH_WANTED,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE)
+ plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE)
+
+ //Disable Medical planes
+ plane_holder.set_vis(VIS_CH_STATUS,FALSE)
+ plane_holder.set_vis(VIS_CH_HEALTH,FALSE)
+ to_chat(src, "Sensor augmentations disabled.")
+
+ hudmode = sensor_type //This is checked in examine.dm on humans, so they can see medical/security records depending on mode
+
+/mob/living/silicon/verb/pose()
+ set name = "Set Pose"
+ set desc = "Sets a description which will be shown when someone examines you."
+ set category = "IC"
+
+ pose = sanitize(input(usr, "This is [src]. It is...", "Pose", null) as text)
+
+/mob/living/silicon/verb/set_flavor()
+ set name = "Set Flavour Text"
+ set desc = "Sets an extended description of your character's features."
+ set category = "IC"
+
+ flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
+
+/mob/living/silicon/binarycheck()
+ return 1
+
+/mob/living/silicon/ex_act(severity)
+ if(!blinded)
+ flash_eyes()
+
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.explosion_modifier))
+ severity = CLAMP(severity + M.explosion_modifier, 1, 4)
+
+ severity = round(severity)
+
+ if(severity > 3)
+ return
+
+ switch(severity)
+ if(1.0)
+ if (stat != 2)
+ adjustBruteLoss(100)
+ adjustFireLoss(100)
+ if(!anchored)
+ gib()
+ if(2.0)
+ if (stat != 2)
+ adjustBruteLoss(60)
+ adjustFireLoss(60)
+ if(3.0)
+ if (stat != 2)
+ adjustBruteLoss(30)
+
+ updatehealth()
+
+/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
+ if(!next_alarm_notice)
+ next_alarm_notice = world.time + SecondsToTicks(10)
+ if(alarm.hidden)
+ return
+ if(alarm.origin && !(get_z(alarm.origin) in using_map.get_map_levels(get_z(src), TRUE, om_range = DEFAULT_OVERMAP_RANGE)))
+ return
+
+ var/list/alarms = queued_alarms[alarm_handler]
+ if(was_raised)
+ // Raised alarms are always set
+ alarms[alarm] = 1
+ else
+ // Alarms that were raised but then cleared before the next notice are instead removed
+ if(alarm in alarms)
+ alarms -= alarm
+ // And alarms that have only been cleared thus far are set as such
+ else
+ alarms[alarm] = -1
+
+/mob/living/silicon/proc/process_queued_alarms()
+ if(next_alarm_notice && (world.time > next_alarm_notice))
+ next_alarm_notice = 0
+
+ var/alarm_raised = 0
+ for(var/datum/alarm_handler/AH in queued_alarms)
+ var/list/alarms = queued_alarms[AH]
+ var/reported = 0
+ for(var/datum/alarm/A in alarms)
+ if(alarms[A] == 1)
+ alarm_raised = 1
+ if(!reported)
+ reported = 1
+ to_chat(src, "
--- [AH.category] Detected ---")
+ raised_alarm(A)
+
+ for(var/datum/alarm_handler/AH in queued_alarms)
+ var/list/alarms = queued_alarms[AH]
+ var/reported = 0
+ for(var/datum/alarm/A in alarms)
+ if(alarms[A] == -1)
+ if(!reported)
+ reported = 1
+ to_chat(src, "
--- [AH.category] Cleared ---")
+ to_chat(src, "\The [A.alarm_name()].")
+
+ if(alarm_raised)
+ to_chat(src, "
\[Show Alerts\]")
+
+ for(var/datum/alarm_handler/AH in queued_alarms)
+ var/list/alarms = queued_alarms[AH]
+ alarms.Cut()
+
+/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
+ to_chat(src, "[A.alarm_name()]!")
+
+/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
+ var/cameratext = ""
+ for(var/obj/machinery/camera/C in A.cameras())
+ cameratext += "[(cameratext == "")? "" : "|"]
[C.c_tag]"
+ to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
+
+
+/mob/living/silicon/proc/is_traitor()
+ return mind && (mind in traitors.current_antagonists)
+
+/mob/living/silicon/proc/is_malf()
+ return mind && (mind in malf.current_antagonists)
+
+/mob/living/silicon/proc/is_malf_or_traitor()
+ return is_traitor() || is_malf()
+
+/mob/living/silicon/adjustEarDamage()
+ return
+
+/mob/living/silicon/setEarDamage()
+ return
+
+/mob/living/silicon/reset_view()
+ . = ..()
+ if(cameraFollow)
+ cameraFollow = null
+
+/mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
+ if(affect_silicon)
+ return ..()
+
+/mob/living/silicon/proc/clear_client()
+ //Handle job slot/tater cleanup.
+ var/job = mind.assigned_role
+
+ job_master.FreeRole(job)
+
+ if(mind.objectives.len)
+ qdel(mind.objectives)
+ mind.special_role = null
+
+ clear_antag_roles(mind)
+
+ ghostize(0)
+ qdel(src)
+
+/mob/living/silicon/has_vision()
+ return 0 //NOT REAL EYES
+
+/mob/living/silicon/can_feed()
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 5b6490c6be9..b36a1ee37c3 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -685,3 +685,6 @@ var/global/image/backplane
return
item.screen_loc = screen_place
+
+/mob/proc/can_feed()
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/_reagent_containers.dm b/code/modules/reagents/reagent_containers/_reagent_containers.dm
index 10196da040d..dba86fba0ce 100644
--- a/code/modules/reagents/reagent_containers/_reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers/_reagent_containers.dm
@@ -91,53 +91,41 @@
return
/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack
- if(!istype(target))
- return 0
+ if(!istype(target) || !target.can_feed())
+ return FALSE
if(!reagents || !reagents.total_volume)
to_chat(user, "
\The [src] is empty.")
- return 1
+ return TRUE
- if(target == user)
- if(istype(user, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
- if(!H.check_has_mouth())
- to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!")
- return
- var/obj/item/blocked = H.check_mouth_coverage()
- if(blocked)
- to_chat(user, "
\The [blocked] is in the way!")
- return
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(!H.check_has_mouth())
+ to_chat(user, "Where do you intend to put \the [src]? [user == target ? "You don't" : "\The [H] doesn't"] have a mouth!")
+ return FALSE
+ var/obj/item/blocked = H.check_mouth_coverage()
+ if(blocked)
+ to_chat(user, "
\The [blocked] is in the way!")
+ return FALSE
- user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things
+ user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things
+ if(user == target)
self_feed_message(user)
reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
- return 1
+ return TRUE
+
else
- if(istype(target, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = target
- if(!H.check_has_mouth())
- to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!")
- return
- var/obj/item/blocked = H.check_mouth_coverage()
- if(blocked)
- to_chat(user, "
\The [blocked] is in the way!")
- return
-
other_feed_message_start(user, target)
-
- user.setClickCooldown(user.get_attack_speed(src))
if(!do_mob(user, target))
- return
-
+ return FALSE
other_feed_message_finish(user, target)
var/contained = reagentlist()
add_attack_logs(user,target,"Fed from [src.name] containing [contained]")
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
- return 1
+ return TRUE
/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level
if(!target.is_open_container() || !target.reagents)