diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 0e433768eb..dc3a7fae17 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -320,6 +320,7 @@
#define MEGAFAUNA_TRAIT "megafauna"
#define DEATHSQUAD_TRAIT "deathsquad"
#define SLIMEPUDDLE_TRAIT "slimepuddle"
+#define CORRUPTED_SYSTEM "corrupted_system"
/// This trait is added by the active directional block system.
#define ACTIVE_BLOCK_TRAIT "active_block"
/// This trait is added by the parry system.
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index a22f0054e8..cd79d31dc0 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -350,10 +350,10 @@
return embeds
-/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
+/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, override_protection = 0)
. = ..()
- var/damage = intensity - get_eye_protection()
+ var/damage = override_protection ? intensity : intensity - get_eye_protection()
if(.) // we've been flashed
var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index e0517b6620..2689f52a3a 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -740,37 +740,157 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
//SYSTEM CORRUPTION FOR ROBOT-PEOPLE//
//////////////////////////////////////
-#define CORRUPTION_CHECK_INTERVAL 10 //Life() is called once every second.. I think? - Doublecheck this, future self.
-#define CORRUPTION_THRESHHOLD_MINOR 10 //Annoyances, to remind you you should get your corruption fixed.
-#define CORRUPTION_THRESHHOLD_MAJOR 40 //Very annoying stuff, go get fixed.
-#define CORRUPTION_THRESHHOLD_CRITICAL 70 //Extremely annoying stuff, possibly life-threatening
+#define CORRUPTION_CHECK_INTERVAL 10//Life() is called once every second.. I think?.
+#define CORRUPTION_THRESHHOLD_MINOR 10 //Above: Annoyances, to remind you you should get your corruption fixed.
+#define CORRUPTION_THRESHHOLD_MAJOR 40 //Above: Very annoying stuff, go get fixed.
+#define CORRUPTION_THRESHHOLD_CRITICAL 70 //Above: Extremely annoying stuff, possibly life-threatening
/mob/living/carbon/proc/handle_corruption()
if(!HAS_TRAIT(src, TRAIT_ROBOTICORGANISM)) //Only robot-people need to care about this
return
corruption_timer++
var/corruption = getToxLoss(toxins_type = TOX_SYSCORRUPT)
+ var/corruption_state
var/timer_req = CORRUPTION_CHECK_INTERVAL
switch(corruption)
if(0 to CORRUPTION_THRESHHOLD_MINOR)
timer_req = INFINITY //Below minor corruption you are fiiine
+ corruption_state = "None"
+ if(CORRUPTION_THRESHHOLD_MINOR to CORRUPTION_THRESHHOLD_MAJOR)
+ corruption_state = "Minor"
if(CORRUPTION_THRESHHOLD_MAJOR to CORRUPTION_THRESHHOLD_CRITICAL)
timer_req -= 1
+ corruption_state = "Major"
if(CORRUPTION_THRESHHOLD_CRITICAL to INFINITY)
timer_req -= 2
+ corruption_state = "Critical"
if(corruption_timer < timer_req)
return
corruption_timer = 0
if(!prob(corruption)) //Lucky you beat the rng roll!
- adjustToxLoss(-0.2, toxins_type = TOX_SYSCORRUPT) //If you succeed the roll, lose a tiny bit of corruption. Only applies past the low threshhold.
return
var/list/whatmighthappen = list()
- whatmighthappen += list("message", "dropthing", "movetile", "shortdeaf", "flopover", "nutriloss", "selfflash")
+ whatmighthappen += list("message" = 4, "dropthing" = 2, "movetile" = 1, "shortdeaf" = 1, "flopover" = 2, "nutriloss" = 1, "selfflash" = 1, "harmies" = 2)
if(corruption >= CORRUPTION_THRESHHOLD_MAJOR)
- whatmighthappen += list("longdeaf", "longknockdown", "shortlimbdisable", "armspasm", "shortblind", "shortstun", "shortmute", "vomit", "halluscinate")
+ whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 2, "shortblind" = 1, "shortstun" = 1, "shortmute" = 2, "vomit" = 1, "halluscinate" = 2)
if(corruption >= CORRUPTION_THRESHHOLD_CRITICAL)
- whatmighthappen += list("receporgandamage", "longlimbdisable", "blindmutedeaf", "longstun", "sleep", "inducetrauma", "amplifycorrupt")
- //WIP
+ whatmighthappen += list("receporgandamage" = 1, "longlimbdisable" = 2, "blindmutedeaf" = 1, "longstun" = 1, "sleep" = 1, "inducetrauma" = 2, "amplifycorrupt" = 4, "changetemp" = 2)
+ var/event = pickweight(whatmighthappen)
+ log_message("has been affected by [event] due to system corruption of [corruption], with a corruption state of [corruption_state]", LOG_ATTACK)
+ switch(event)
+ if("message")
+ to_chat(src, "System malfunction avoided by hardware safeguards - intervention recommended.")
+ adjustToxLoss(-0.2, toxins_type = TOX_SYSCORRUPT) //If you roll this, your system safeguards caught onto the system corruption and neutralised a bit of it.
+ if("dropthing")
+ drop_all_held_items()
+ to_chat(src, "Error - Malfunction in arm circuitry.")
+ if("movetile")
+ if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !ismovable(loc))
+ step(src, pick(GLOB.cardinals))
+ to_chat(src, "Error - Malfuction in movement control subsystem.")
+ if("shortdeaf")
+ ADD_TRAIT(src, TRAIT_DEAF, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_hearing), 5 SECONDS)
+ to_chat(src, "ZZZZT")
+ if("flopover")
+ DefaultCombatKnockdown(1)
+ to_chat(src, "Error - Malfuction in actuator circuitry.")
+ if("nutriloss")
+ nutrition = max(0, nutrition - 50)
+ to_chat(src, "Power surge detected in internal battery cell.")
+ if("selfflash")
+ if(flash_act(override_protection = 1))
+ confused += 2
+ to_chat(src, "Error - Sensory system overload detected!")
+ if("harmies")
+ a_intent = INTENT_HARM
+ to_chat(src, "Intent subsystem successfully recalibrated.")
+ if("longdeaf")
+ ADD_TRAIT(src, TRAIT_DEAF, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_hearing), 20 SECONDS)
+ to_chat(src, "Hearing subsystem successfully shutdown.")
+ if("longknockdown")
+ DefaultCombatKnockdown(50)
+ to_chat(src, "Significant error in actuator subsystem - Rebooting.")
+ if("shortlimbdisable")
+ var/disabled_type = pick(list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG))
+ ADD_TRAIT(src, disabled_type, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_limb, disabled_type), 5 SECONDS)
+ to_chat(src, "Error - Limb control subsystem partially shutdown, rebooting.")
+ if("shortblind")
+ ADD_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_vision), 5 SECONDS)
+ to_chat(src, ">span class='warning'>Visual receptor shutdown detected - Initiating reboot.")
+ if("shortstun")
+ Stun(30)
+ to_chat(src, "Deadlock detected in primary systems, error code [rand(101, 999)].")
+ if("shortmute")
+ ADD_TRAIT(src, TRAIT_MUTE, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_speech), 5 SECONDS)
+ to_chat(src, "Communications matrix successfully shutdown for maintenance.")
+ if("vomit")
+ to_chat(src, "Ejecting contaminant.")
+ vomit()
+ if("halluscinate")
+ hallucination += 20 //Doesn't give a cue
+ if("receporgandamage")
+ adjustOrganLoss(ORGAN_SLOT_EARS, rand(10, 20))
+ adjustOrganLoss(ORGAN_SLOT_EYES, rand(10, 20))
+ to_chat(src, "Power spike detected in autitory and visual systems!")
+ if("longlimbdisable")
+ var/disabled_type = pick(list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG))
+ ADD_TRAIT(src, disabled_type, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_limb, disabled_type), 25 SECONDS)
+ to_chat(src, "Fatal error in limb control subsystem - rebooting.")
+ if("blindmutedeaf")
+ ADD_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_vision), (rand(10, 25)) SECONDS)
+ ADD_TRAIT(src, TRAIT_DEAF, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_hearing), (rand(15, 35)) SECONDS)
+ ADD_TRAIT(src, TRAIT_MUTE, CORRUPTED_SYSTEM)
+ addtimer(CALLBACK(src, .proc/reenable_speech), (rand(20, 45)) SECONDS)
+ to_chat(src, "Fatal error in multiple systems - Performing recovery.")
+ if("longstun")
+ Stun(80)
+ to_chat(src, "")
+ if("sleep")
+ addtimer(CALLBACK(src, .proc/forcesleep), (rand(6, 10)) SECONDS)
+ to_chat(src, "Priority 1 shutdown order received in operating system - Preparing powerdown.")
+ if("inducetrauma")
+ var/resistance = pick(
+ 65;TRAUMA_RESILIENCE_BASIC,
+ 35;TRAUMA_RESILIENCE_SURGERY)
+
+ var/trauma_type = pickweight(list(
+ BRAIN_TRAUMA_MILD = 80,
+ BRAIN_TRAUMA_SEVERE = 10))
+ gain_trauma_type(trauma_type, resistance) //Gaining the trauma will inform them
+ if("amplifycorrupt")
+ adjustToxLoss(10, toxins_type = TOX_SYSCORRUPT)
+ to_chat(src, "System safeguards failing - Action urgently required.")
+ if("changetemp")
+ adjust_bodytemperature(pick(list(-70, 70)))
+ to_chat(src, "Warning - Fatal coolant flow error at node [rand(6, 99)]!")
+
+/mob/living/carbon/proc/reenable_limb(disabled_limb)
+ REMOVE_TRAIT(src, disabled_limb, CORRUPTED_SYSTEM)
+ to_chat(src, "Limb control subsystem successfully rebooted.")
+
+/mob/living/carbon/proc/reenable_hearing()
+ REMOVE_TRAIT(src, TRAIT_DEAF, CORRUPTED_SYSTEM)
+ to_chat(src, "Hearing restored.")
+
+/mob/living/carbon/proc/reenable_vision()
+ REMOVE_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
+ to_chat(src, "Visual receptors back online.")
+
+/mob/living/carbon/proc/reenable_speech()
+ REMOVE_TRAIT(src, TRAIT_MUTE, CORRUPTED_SYSTEM)
+ to_chat(src, "Communications subsystem operational.")
+
+/mob/living/carbon/proc/forcesleep(time = 100)
+ to_chat(src, "Preparations complete, powering down.")
+ Sleeping(time, 0)
#undef CORRUPTION_CHECK_INTERVAL
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 19adb7b787..8e39dc5234 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -522,8 +522,8 @@
//called when the mob receives a bright flash
-/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
- if(get_eye_protection() < intensity && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND))))
+/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash, override_protection = 0)
+ if((override_protection || get_eye_protection() < intensity) && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND))))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return TRUE