From bdf63a9d4b93bc0fadd46524be7f8177550ee72d Mon Sep 17 00:00:00 2001 From: atermonera Date: Thu, 7 Oct 2021 16:39:04 -0800 Subject: [PATCH] Adds can_feed proc --- code/modules/mob/living/silicon/silicon.dm | 845 +++++++++--------- code/modules/mob/mob_helpers.dm | 3 + .../reagent_containers/_reagent_containers.dm | 48 +- 3 files changed, 445 insertions(+), 451 deletions(-) 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)