diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 2fb6a2f985f..0061a371d0c 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -825,6 +825,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_CURRENTLY_CLEANING "currently_cleaning" // unique trait sources, still defines +#define EMP_TRAIT "emp_trait" #define STATUE_MUTE "statue" #define CHANGELING_DRAIN "drain" /// changelings with this trait can no longer talk over the hivemind diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index 9aed1d30072..26ab9e850b6 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -188,6 +188,9 @@ /datum/client_colour/glass_colour/nightmare colour = list(255,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, -130,0,0,0) //every color is either red or black +/datum/client_colour/malfunction + colour = list(/*R*/ 0,0,0,0, /*G*/ 0,175,0,0, /*B*/ 0,0,0,0, /*A*/ 0,0,0,1, /*C*/0,-130,0,0) // Matrix colors + /datum/client_colour/monochrome colour = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) priority = PRIORITY_HIGH //we can't see colors anyway! diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 45be69acd28..cf0d3317f3b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -500,19 +500,8 @@ . = ..() if(. & EMP_PROTECT_CONTENTS) return - var/informed = FALSE for(var/obj/item/bodypart/L as anything in src.bodyparts) - if(!IS_ORGANIC_LIMB(L)) - if(!informed) - to_chat(src, span_userdanger("You feel a sharp pain as your robotic limbs overload.")) - informed = TRUE - switch(severity) - if(1) - L.receive_damage(0,10) - Paralyze(200) - if(2) - L.receive_damage(0,5) - Paralyze(100) + L.emp_act() /mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc var/list/damaged = list() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index b23b48dc1ba..131afd6f2c3 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -1134,3 +1134,27 @@ owner.update_body_parts() else update_icon_dropped() + +/obj/item/bodypart/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_WIRES || !(bodytype & BODYTYPE_ROBOTIC)) + return FALSE + owner.visible_message(span_danger("[owner]'s [src.name] seems to malfunction!")) + + var/time_needed = 10 SECONDS + var/brute_damage = 5 + 1.5 // Augments reduce brute damage by 5. + var/burn_damage = 4 + 2.5 // As above, but for burn it's 4. + + if(severity == EMP_HEAVY) + time_needed *= 2 + brute_damage *= 2 + burn_damage *= 2 + + receive_damage(brute_damage, burn_damage) + do_sparks(number = 1, cardinal_only = FALSE, source = owner) + ADD_TRAIT(src, TRAIT_PARALYSIS, EMP_TRAIT) + addtimer(CALLBACK(src, PROC_REF(un_paralyze)), time_needed) + return TRUE + +/obj/item/bodypart/proc/un_paralyze() + REMOVE_TRAITS_IN(src, EMP_TRAIT) diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index e4663d271ed..7e52016748a 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -100,6 +100,15 @@ damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) +/obj/item/bodypart/leg/left/robot/emp_act(severity) + . = ..() + if(!.) + return + owner.Knockdown(severity == EMP_HEAVY ? 20 SECONDS : 10 SECONDS) + if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways. + return + to_chat(owner, span_danger("As your [src.name] unexpectedly malfunctions, it causes you to fall to the ground!")) + /obj/item/bodypart/leg/right/robot name = "cyborg right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." @@ -130,6 +139,15 @@ damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) +/obj/item/bodypart/leg/right/robot/emp_act(severity) + . = ..() + if(!.) + return + owner.Knockdown(severity == EMP_HEAVY ? 20 SECONDS : 10 SECONDS) + if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways. + return + to_chat(owner, span_danger("As your [src.name] unexpectedly malfunctions, it causes you to fall to the ground!")) + /obj/item/bodypart/chest/robot name = "cyborg torso" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." @@ -161,6 +179,19 @@ var/wired = FALSE var/obj/item/stock_parts/cell/cell = null +/obj/item/bodypart/chest/robot/emp_act(severity) + . = ..() + if(!.) + return + to_chat(owner, span_danger("Your [src.name]'s logic boards temporarily become unresponsive!")) + if(severity == EMP_HEAVY) + owner.Stun(6 SECONDS) + owner.Shake(pixelshiftx = 5, pixelshifty = 2, duration = 4 SECONDS) + return + + owner.Stun(3 SECONDS) + owner.Shake(pixelshiftx = 3, pixelshifty = 0, duration = 2.5 SECONDS) + /obj/item/bodypart/chest/robot/get_cell() return cell @@ -273,6 +304,22 @@ var/obj/item/assembly/flash/handheld/flash1 = null var/obj/item/assembly/flash/handheld/flash2 = null +#define EMP_GLITCH "EMP_GLITCH" + +/obj/item/bodypart/head/robot/emp_act(severity) + . = ..() + if(!.) + return + to_chat(owner, span_danger("Your [src.name]'s optical transponders glitch out and malfunction!")) + + var/glitch_duration = severity == EMP_HEAVY ? 15 SECONDS : 7.5 SECONDS + + owner.add_client_colour(/datum/client_colour/malfunction) + + addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob/living/carbon/human, remove_client_colour), /datum/client_colour/malfunction), glitch_duration) + +#undef EMP_GLITCH + /obj/item/bodypart/head/robot/handle_atom_del(atom/head_atom) if(head_atom == flash1) flash1 = null