From d5c9204b7892106d0ff4753600573148b9f81fa2 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Fri, 12 Dec 2025 04:01:08 -0500 Subject: [PATCH] Psi Rework Part 1: The Miracle and the Sleeper (#21584) image **This is but one of several PRs as part of Project Anabasis, and is a necessary building-block for a Traits System and a Skills System** This PR was essentially prompted by recent lore changes to Skrell that weren't yet existing in the game, so I'm kicking off this as a PR to start a series of more meaningful psionic reworks. With a focus on Components and Signals as a way of dramatically increasing the systems interactivity of psionics. With this PR, mobs have an effective "Psi-Sensitivity" that can be checked by psionic effects, and influence a wide variety of interactions. Psi-Sensitivity is calculated based on a Signal interaction, whereby multiple responding sources have a chance to respond to the signal and influence the end result of the calculation. For now there still remains a cutout specifically for owners of a Psi-Complexus(Which is just Skrell and Antag Psions), who have a bonus to the psi-sensitivity check equal to their PSI-RATING. That being 1 for Skrell, and 2 for antag psions. But eventually in the future this should be replaced with a standalone component separate from the concept of "Sending" The other common sources of sensitivity currently are the Psionic Receiver implant, MindShield, and Mind Blanker implants. With Psionic Receivers giving a bonus to psi-sensitivity, and the latter two giving a penalty to psi-sensitivity. Both MindShields and Mind Blankers are now unified in how they interact with psionics, both using the same system of Signals without a hardcoded check for the mindshield. As an important distinction to make, Psi-Sensitivity is NOT the same thing as being Psionic. Actually Psionic characters like Skrell have a big bonus to their sensitivity. It's more a measurement of how receptive a character is to Receiving (separate from Sending) psionic influences. You can actually be capable of using psionic abilities, but have a sensitivity of 0, effectively meaning such a character can "Send but not Receive" psi influences. - [x] I have tested this PR and have verified that it works, you're welcome. --- code/__DEFINES/dcs/signals.dm | 3 ++ .../weapons/implants/implants/mindshield.dm | 20 ++++++++ .../mob/living/carbon/human/human_powers.dm | 13 ++--- code/modules/organs/organ_external.dm | 18 ++----- .../subtypes/augment/augments/mind_blanker.dm | 34 ++++++++++++- .../subtypes/augment/augments/psi_receiver.dm | 35 +++++++++++++- code/modules/psionics/abilities/commune.dm | 4 +- .../abilities/emotional_suggestion.dm | 6 +-- code/modules/psionics/abilities/read_mind.dm | 4 +- code/modules/psionics/mob/mob_helpers.dm | 48 +++++++++++++++---- .../Chemistry-Reagents-Drugs.dm | 6 +-- .../artifact/artifact_crystal_madness.dm | 2 +- code/modules/shareddream/dream_entry.dm | 26 ++++++---- ...llfirejag-psionic-sensitivity-refactor.yml | 4 ++ 14 files changed, 167 insertions(+), 56 deletions(-) create mode 100644 html/changelogs/hellfirejag-psionic-sensitivity-refactor.yml diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 7982de6f0d8..f3e05863ddb 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -74,4 +74,7 @@ /// Raised on the target of a "mind-affecting" psionic power. #define COMSIG_PSI_MIND_POWER "psi_block_check" +/// Raised on a mob to check it's psi-sensitivity rating. This is not the same thing as checking if someone is psionic, but psionic people have an innate bonus to the check. +#define COMSIG_PSI_CHECK_SENSITIVITY "psi_check_sensitivity" + /*******Component Specific Signals*******/ diff --git a/code/game/objects/items/weapons/implants/implants/mindshield.dm b/code/game/objects/items/weapons/implants/implants/mindshield.dm index 3645aa9b63a..f7135a29658 100644 --- a/code/game/objects/items/weapons/implants/implants/mindshield.dm +++ b/code/game/objects/items/weapons/implants/implants/mindshield.dm @@ -10,6 +10,7 @@ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_ILLEGAL = 3) default_action_type = null known = TRUE + var/sensitivity_modifier = -1 /obj/item/implant/mindshield/get_data() . = {" @@ -24,6 +25,8 @@ Integrity: Implant will last so long as the nanobots are inside the bloodstream."} /obj/item/implant/mindshield/implanted(mob/M) + RegisterSignal(M, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) + RegisterSignal(M, COMSIG_PSI_MIND_POWER, PROC_REF(cancel_power), override = TRUE) to_chat(M, SPAN_GOOD("You feel your mind steel against external suggestion!")) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M @@ -38,6 +41,23 @@ return FALSE return TRUE +/obj/item/implant/mindshield/removed() + . = ..() + if(!imp_in) + return + + UnregisterSignal(imp_in, COMSIG_PSI_CHECK_SENSITIVITY) + UnregisterSignal(imp_in, COMSIG_PSI_MIND_POWER) + +/obj/item/implant/mindshield/proc/modify_sensitivity(var/implantee, var/effective_sensitivity) + SIGNAL_HANDLER + *effective_sensitivity += sensitivity_modifier + +/obj/item/implant/mindshield/proc/cancel_power(var/implantee, var/caster, var/cancelled) + SIGNAL_HANDLER + *cancelled = TRUE + to_chat(implantee, SPAN_DANGER("Your [name] buzzes angrily.")) + /obj/item/implant/mindshield/emp_act(severity) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 61620471722..344140e2ea6 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -240,9 +240,12 @@ if(M.stat == 2) M.gib() - -// Simple mobs cannot use Skrellepathy -/mob/proc/has_psionics() +/** + * A binary yes or no check as to whether or not a target has a Psi Complexus. + * This proc is to be DEPRECATED, nothing new should check it. + * Use check_psi_sensitivity() instead for all your psionic interactions. + */ +/atom/movable/proc/has_psionics() return FALSE /mob/living/carbon/human/has_psionics() @@ -327,15 +330,13 @@ to_chat(M,"[src] telepathically says to [target]: [text]") var/mob/living/carbon/human/H = target - if (target.has_psionics()) + if (target.check_psi_sensitivity()) to_chat(H,"You instinctively sense [src] sending their thoughts into your mind, hearing: [text]") else if(prob(25) && (target.mind && target.mind.assigned_role=="Chaplain")) to_chat(H,"You sense [src]'s thoughts enter your mind, whispering quietly: [text]") else to_chat(H,"You feel pressure behind your eyes as alien thoughts enter your mind: [text]") if(istype(H)) - if (target.has_psionics()) - return if(prob(10) && !(H.species.flags & NO_BLOOD)) to_chat(H,SPAN_WARNING("Your nose begins to bleed...")) H.drip(3) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 18f83cc3362..9e8ff63f958 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -400,20 +400,10 @@ /// Psionics and psionically deaf species take varying amounts of damage from psionic abilities. if(psionic) - if(!owner.has_psionics()) - brute *= 0.9 - burn *= 0.9 - else if(owner.psi) - var/psi_rank = owner.psi.get_rank() - if(psi_rank == PSI_RANK_SENSITIVE) - brute *= 1.05 - burn *= 1.05 - else if(psi_rank == PSI_RANK_HARMONIOUS) - brute *= 1.1 - burn *= 1.1 - else if(psi_rank == PSI_RANK_APEX) - brute *= 1.2 - burn *= 1.2 + // Damage modifier is 0.9 for no psionics at all, 1 for baseline psychic, and an extra 0.1 per equivalent rank above baseline. + var/psi_damage_modifier = 1 + (0.1 * (owner.check_psi_sensitivity() - 1)) + brute *= psi_damage_modifier + burn *= psi_damage_modifier if(status & ORGAN_BROKEN && prob(40) && brute) if(owner && (owner.can_feel_pain()) && owner.stat == CONSCIOUS) diff --git a/code/modules/organs/subtypes/augment/augments/mind_blanker.dm b/code/modules/organs/subtypes/augment/augments/mind_blanker.dm index 7235d68166d..7de64ff242e 100644 --- a/code/modules/organs/subtypes/augment/augments/mind_blanker.dm +++ b/code/modules/organs/subtypes/augment/augments/mind_blanker.dm @@ -5,6 +5,7 @@ icon_state = "mind_blanker" organ_tag = BP_AUG_MIND_BLANKER parent_organ = BP_HEAD + var/sensitivity_modifier = -1 /obj/item/organ/internal/augment/bioaug/mind_blanker/Initialize() . = ..() @@ -12,6 +13,7 @@ return RegisterSignal(owner, COMSIG_PSI_MIND_POWER, PROC_REF(cancel_power), override = TRUE) + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) /obj/item/organ/internal/augment/bioaug/mind_blanker/replaced() . = ..() @@ -19,6 +21,7 @@ return RegisterSignal(owner, COMSIG_PSI_MIND_POWER, PROC_REF(cancel_power), override = TRUE) + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) /obj/item/organ/internal/augment/bioaug/mind_blanker/removed() . = ..() @@ -26,10 +29,22 @@ return UnregisterSignal(owner, COMSIG_PSI_MIND_POWER) + UnregisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY) /obj/item/organ/internal/augment/bioaug/mind_blanker/proc/cancel_power(var/implantee, var/caster, var/cancelled) SIGNAL_HANDLER + if(is_broken()) + return + *cancelled = TRUE + to_chat(implantee, SPAN_DANGER("Your mind wriggles as it repulses an outside thought.")) + +/obj/item/organ/internal/augment/bioaug/mind_blanker/proc/modify_sensitivity(var/implantee, var/effective_sensitivity) + SIGNAL_HANDLER + if(is_broken()) + return + + *effective_sensitivity += sensitivity_modifier /obj/item/organ/internal/augment/bioaug/mind_blanker_lethal name = "lethal mind blanker" @@ -38,6 +53,7 @@ + "This enhanced variant of a mind blanker includes a psionic trap which inflicts severe neural damage on anyone attempting to read the user's mind." organ_tag = BP_AUG_MIND_BLANKER_L parent_organ = BP_HEAD + var/sensitivity_modifier = -1 /obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/Initialize() . = ..() @@ -45,6 +61,7 @@ return RegisterSignal(owner, COMSIG_PSI_MIND_POWER, PROC_REF(cancel_power_lethal), override = TRUE) + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) /obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/replaced() . = ..() @@ -52,6 +69,7 @@ return RegisterSignal(owner, COMSIG_PSI_MIND_POWER, PROC_REF(cancel_power_lethal), override = TRUE) + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) /obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/removed() . = ..() @@ -59,12 +77,24 @@ return UnregisterSignal(owner, COMSIG_PSI_MIND_POWER) + UnregisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY) -/obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/proc/cancel_power_lethal(var/implantee, var/caster, var/cancelled) +/obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/proc/cancel_power_lethal(var/mob/living/carbon/human/implantee, var/caster, var/cancelled) SIGNAL_HANDLER + if(is_broken()) + return + *cancelled = TRUE + to_chat(implantee, SPAN_DANGER("Your mind wriggles as it repulses an outside thought.")) if(isliving(caster)) var/mob/living/victim = caster victim.adjustBrainLoss(20) victim.confused += 20 - to_chat(victim, SPAN_DANGER("Agony lances through my mind as [src]'s mind clamps down upon me!")) + to_chat(victim, SPAN_DANGER("Agony lances through my mind as [implantee.name]'s mind clamps down upon me!")) + +/obj/item/organ/internal/augment/bioaug/mind_blanker_lethal/proc/modify_sensitivity(var/implantee, var/effective_sensitivity) + SIGNAL_HANDLER + if(is_broken()) + return + + *effective_sensitivity += sensitivity_modifier diff --git a/code/modules/organs/subtypes/augment/augments/psi_receiver.dm b/code/modules/organs/subtypes/augment/augments/psi_receiver.dm index 72d4e59e927..152e0146f40 100644 --- a/code/modules/organs/subtypes/augment/augments/psi_receiver.dm +++ b/code/modules/organs/subtypes/augment/augments/psi_receiver.dm @@ -1,6 +1,37 @@ /obj/item/organ/internal/augment/psi name = "psionic receiver" - desc = "An augment installed into the head that functions as a surrogate " \ - + "for a missing zona bovinae, also functioning as a filter for the psionically-challenged." + desc = "A cybernetic implant that allows for the carrier of a receiver to be sensitive enough to accept and interpret psionic signals " \ + + "Essentially an implanted and carefully encased cultured zona bovinae, these receivers are regularly found within dionae and vaurca who otherwise lack this specialized portion of the brain entirely." \ + + "It is also used by other sophonts who regularly interact with skrell to the point of necessitating it." \ + + "Some psionically weak skrell will also implant themselves with a receiver in the same way a hearing aid is utilized." organ_tag = BP_AUG_PSI parent_organ = BP_HEAD + var/sensitivity_modifier = 1 + +/obj/item/organ/internal/augment/psi/Initialize() + . = ..() + if(!owner) + return + + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) + +/obj/item/organ/internal/augment/psi/replaced() + . = ..() + if(!owner) + return + + RegisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY, PROC_REF(modify_sensitivity), override = TRUE) + +/obj/item/organ/internal/augment/psi/removed() + . = ..() + if(!owner) + return + + UnregisterSignal(owner, COMSIG_PSI_CHECK_SENSITIVITY) + +/obj/item/organ/internal/augment/psi/proc/modify_sensitivity(var/implantee, var/effective_sensitivity) + SIGNAL_HANDLER + if(is_broken()) + return + + *effective_sensitivity += sensitivity_modifier diff --git a/code/modules/psionics/abilities/commune.dm b/code/modules/psionics/abilities/commune.dm index ca020561208..4a5b4e62aec 100644 --- a/code/modules/psionics/abilities/commune.dm +++ b/code/modules/psionics/abilities/commune.dm @@ -62,9 +62,7 @@ to_chat(M, "[user] psionically says to [target]: [text]") var/mob/living/carbon/human/H = target - if(H.has_psionics()) + if(H.check_psi_sensitivity() >= 1) to_chat(H, SPAN_CULT("You instinctively sense [user] passing a thought into your mind: [text]")) - else if(target.has_psi_aug()) - to_chat(H, SPAN_CULT("You sense [user]'s psyche link with your psi-receiver, a thought sliding into your mind: [text]")) else to_chat(H, SPAN_ALIEN("A thought from outside your consciousness slips into your mind: [text]")) diff --git a/code/modules/psionics/abilities/emotional_suggestion.dm b/code/modules/psionics/abilities/emotional_suggestion.dm index 2c6d6d9b892..df6dc7166bd 100644 --- a/code/modules/psionics/abilities/emotional_suggestion.dm +++ b/code/modules/psionics/abilities/emotional_suggestion.dm @@ -62,9 +62,7 @@ to_chat(M, "[user] psionically suggests an emotion to [target]: [text]") var/mob/living/carbon/human/H = target - if(H.has_psionics()) - to_chat(H, SPAN_NOTICE("You feel an emotion of [text] washing through your mind.")) - else if(target.has_psi_aug()) - to_chat(H, SPAN_NOTICE("You sense [user]'s psyche link with your psi-receiver, and an emotion envelops your mind: [text].")) + if(H.check_psi_sensitivity() > 0) + to_chat(H, SPAN_NOTICE("You sense [user]'s psyche link with your own, and an emotion of [text] washes through your mind.")) else to_chat(H, SPAN_NOTICE("An emotion from outside your consciousness slips into your mind: [text].")) diff --git a/code/modules/psionics/abilities/read_mind.dm b/code/modules/psionics/abilities/read_mind.dm index 23cebce635d..41b04147bd5 100644 --- a/code/modules/psionics/abilities/read_mind.dm +++ b/code/modules/psionics/abilities/read_mind.dm @@ -39,8 +39,8 @@ return var/safe_mode = FALSE - var/mob/living/L = user - if(L.psi.get_rank() < PSI_RANK_HARMONIOUS) + // Safe mode triggers if the caster's psi-sensitivity isn't 2 or more points greater than the receiver's sensitivity. + if(user.check_psi_sensitivity() - target.check_psi_sensitivity() < PSI_RANK_HARMONIOUS) safe_mode = TRUE user.visible_message(SPAN_WARNING("[user] lays a palm on [hit_atom]'s forehead...")) diff --git a/code/modules/psionics/mob/mob_helpers.dm b/code/modules/psionics/mob/mob_helpers.dm index 00ab36e535a..6d5fa21d04b 100644 --- a/code/modules/psionics/mob/mob_helpers.dm +++ b/code/modules/psionics/mob/mob_helpers.dm @@ -1,25 +1,53 @@ -/mob/living/proc/has_psi_aug() +/// !DEPRECATED: GO USE check_psi_sensitivity() INSTEAD +/atom/movable/proc/has_psi_aug() return FALSE /mob/living/carbon/has_psi_aug() var/obj/item/organ/internal/augment/psi/psiaug = internal_organs_by_name[BP_AUG_PSI] return psiaug && !psiaug.is_broken() -/mob/living/proc/is_psi_blocked(mob/user) - return !has_psionics() - -/mob/living/carbon/is_psi_blocked(mob/user) +/** + * Checks via signal if the target is blocked from RECEIVING psionic messages. + * Traditionally, most organic life can in some way RECEIVE psionic messages via a Zona Bovinae, though some lack it. + * Implants, drugs, and some psi powers may temporarily block RECEIVING. + * + * This is NOT a check for "Can Receive?", if you need that go use check_psi_sensitivity(). + */ +/atom/movable/proc/is_psi_blocked(mob/user) var/cancelled = FALSE SEND_SIGNAL(src, COMSIG_PSI_MIND_POWER, user, &cancelled) if(cancelled || (!has_zona_bovinae() && !has_psi_aug())) return SPAN_WARNING("[src]'s mind is inaccessible, like hitting a brick wall.") - for (var/obj/item/implant/mindshield/I in src) - if (I.implanted) - return SPAN_WARNING("[src]'s mind is inaccessible, like hitting a brick wall.") +/** + * Check the "effective psi-sensitivity" of a mob. AKA: The target's RECEIVING statistic. + * This can be influenced by anything wishing to reply to the signal, such as implants, drugs, other psi-powers, etc. + * It also includes the actual psi-sensitivity of real psionics such as Skrell. + * This returns a float that is any real number (including negatives). + * + * A typical human will (assuming they have no positive temporary modifiers) will return anywhere from -2 and 0, + * so for a "not-psi sensitive" check, you'll want to do check_psi_sensitivity() <= 0. + * + * A typical "real psionic" will return between 1 and 2. Possibly more. + * So to check for "Yes they're psychic", look for check_psi_sensitivity >= 1 + * + * And for "Any positive mods allowed", use check_psi_sensitivity > 0 + */ +/atom/movable/proc/check_psi_sensitivity() + var/effective_sensitivity = 0 + SEND_SIGNAL(src, COMSIG_PSI_CHECK_SENSITIVITY, &effective_sensitivity) + return effective_sensitivity + +/mob/living/check_psi_sensitivity() + var/effective_sensitivity = ..() + if(psi) + effective_sensitivity += psi.get_rank() + return effective_sensitivity + +/atom/movable/proc/has_zona_bovinae() return FALSE -/mob/living/proc/has_zona_bovinae() +/mob/living/has_zona_bovinae() return TRUE /mob/living/carbon/has_zona_bovinae() @@ -27,7 +55,7 @@ return FALSE return TRUE -/mob/living/proc/is_psi_pingable() +/atom/movable/proc/is_psi_pingable() return !is_psi_blocked() /mob/living/simple_animal/is_psi_pingable() diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm index 4f19a997a97..94fa0b662b3 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm @@ -470,13 +470,13 @@ if(!prob(3)) return - if(M.psi && M.psi.get_rank() >= PSI_RANK_SENSITIVE) + if(M.check_psi_sensitivity() >= PSI_RANK_SENSITIVE) to_chat(M, SPAN_ALIEN(pick("You can see the thoughts of those around you dancing in the air.", "You feel as if your mind has opened even further, your thought-field expanding.", "It's difficult to contain your thoughts - but why hide them anyway?", "You feel safe and comfortable."))) else to_chat(M, SPAN_GOOD(pick("You can almost see the currents of air as they dance around you.", "You see the colours around you beginning to bleed together.", "You feel safe and comfortable."))) /singleton/reagent/wulumunusha/overdose(mob/living/carbon/M, alien, removed = 0, scale = 1, datum/reagents/holder) - if(!M.psi || M.psi.get_rank() < PSI_RANK_SENSITIVE) + if(!M.psi || M.check_psi_sensitivity() < PSI_RANK_SENSITIVE) return M.hallucination = max(M.hallucination, 10 * scale) //light hallucinations that afflict the psionically sensitive. @@ -574,7 +574,7 @@ M.add_chemical_effect(CE_PULSE, -1) var/message_list = list("You feel soothed and at ease.", "You feel like sharing the wonderful memories and feelings you're experiencing.", "You feel like you're floating off the ground.", "You don't want this feeling to end.", "You wish to please all those around you.", "You feel particularly susceptible to persuasion.", "Everyone is so trustworthy nowadays.") var/message_type = "good" - if(M.psi && M.psi.get_rank() >= PSI_RANK_SENSITIVE) + if(M.check_psi_sensitivity() >= PSI_RANK_SENSITIVE) message_list += list("You can see the thoughts of those around you dancing in the air.", "You feel as if your mind has opened even further, your thought-field expanding.", "It's difficult to contain your thoughts - but why hide them anyway?") message_type = "alium" else diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_crystal_madness.dm b/code/modules/research/xenoarchaeology/artifact/artifact_crystal_madness.dm index 9b82b0260dc..5223a4e2e2b 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_crystal_madness.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_crystal_madness.dm @@ -30,7 +30,7 @@ // get mobs var/list/affected_mobs = list() for(var/mob/living/carbon/human/mob_in_range in get_hearers_in_LOS(world.view, src)) - if((!mob_in_range.is_psi_blocked(src)) && (mob_in_range.has_psionics() || mob_in_range.has_psi_aug() || mob_in_range.has_zona_bovinae())) + if((!mob_in_range.is_psi_blocked(src)) && ((mob_in_range.check_psi_sensitivity() > 0) || mob_in_range.has_zona_bovinae())) affected_mobs += mob_in_range // set up timer for delayed effects diff --git a/code/modules/shareddream/dream_entry.dm b/code/modules/shareddream/dream_entry.dm index 311f018a4d7..a9a11bbae60 100644 --- a/code/modules/shareddream/dream_entry.dm +++ b/code/modules/shareddream/dream_entry.dm @@ -10,11 +10,16 @@ GLOBAL_LIST_EMPTY_TYPED(dream_entries, /turf) /mob/living/carbon/human/proc/handle_shared_dreaming(var/force_wakeup = FALSE) SHOULD_NOT_SLEEP(TRUE) + if(is_psi_blocked(src)) // Can't enter the dream if the caster is blocked from RECEIVING. It's a two-way street. + return - // If they're an Unconsious person with the abillity to do Skrellepathy. - // If either changes, they should be nocked back to the real world. + // This is one of the legitimate uses for has_psionics() that should be kept even though has_psionics() is deprecated. + // Entering the dream requires the caster be capable of SENDING. + var/is_psionic = has_psionics() + + // Entering the dream requires that the caster either be capable of SENDING, or has a "guide" performing the SENDING on their behalf. var/mob/living/carbon/human/srom_puller = srom_pulled_by?.resolve() - if((has_psionics() || (srom_puller && Adjacent(srom_puller))) && stat == UNCONSCIOUS && sleeping > 1) + if((is_psionic || (srom_puller && Adjacent(srom_puller))) && stat == UNCONSCIOUS && sleeping > 1) if(!istype(bg) && client) // Don't spawn a brainghost if we're not logged in. bg = new /mob/living/brain_ghost(src, src) // Generate a new brainghost. if(isnull(bg)) // Prevents you from getting kicked if the brain ghost didn't spawn - geeves @@ -27,13 +32,14 @@ GLOBAL_LIST_EMPTY_TYPED(dream_entries, /turf) to_chat(bg, SPAN_WARNING("Whilst in shared dreaming, you find it difficult to hide your secrets.")) if(willfully_sleeping) to_chat(bg, "To wake up, use the \"Awaken\" verb in the IC tab.") - if(!srom_pulling && has_psionics()) + if(!srom_pulling && is_psionic) var/obj/item/grab/G = r_hand if(!G) G = l_hand if(G) var/mob/living/carbon/human/victim = G.affecting - if(ishuman(victim) && !isSynthetic(victim) && victim.is_psi_pingable(srom_puller)) + // Victims must be capable of RECEIVING. + if(!victim.is_psi_blocked(src) && ((victim.check_psi_sensitivity() > 0) || victim.has_zona_bovinae())) to_chat(bg, SPAN_NOTICE("You have taken [victim] to the Srom with you.")) victim.srom_pulled_by = WEAKREF(src) srom_pulling = WEAKREF(victim) @@ -47,7 +53,7 @@ GLOBAL_LIST_EMPTY_TYPED(dream_entries, /turf) if(istype(bg) || force_wakeup) // If we choose to be asleep, keep sleeping. if(willfully_sleeping && sleeping && stat == UNCONSCIOUS) - if(has_psionics() || srom_pulled_by) + if(is_psionic || srom_pulled_by) sleeping = 5 return for(var/thing in SSpsi.processing) @@ -61,15 +67,17 @@ GLOBAL_LIST_EMPTY_TYPED(dream_entries, /turf) var/mob/return_mob = src if(srom_pulled_by) - if(!has_psi_aug()) + var/sensitivity = check_psi_sensitivity() + if(sensitivity <= 0) dizziness += 40 confused += 40 slurring += 40 eye_blurry += 40 return_text += " You feel dizzy, confused and weird..." else - return_text += " Your augment staves off most of the post-Srom pull symptoms, but you still feel like your mind is clouded." - adjustBrainLoss(10) + return_text += " You stave off most of the post-Srom pull symptoms, but you still feel like your mind is clouded." + // Non-Psions can have a RECEIVING stat, so we'll account for it by giving them a leeway on the brain damage if they're sufficiently sensitive. + adjustBrainLoss(10 - min(10, 5 * sensitivity)) srom_pulled_by = null var/mob/living/carbon/human/victim = srom_pulling?.resolve() diff --git a/html/changelogs/hellfirejag-psionic-sensitivity-refactor.yml b/html/changelogs/hellfirejag-psionic-sensitivity-refactor.yml new file mode 100644 index 00000000000..1d77cd6052f --- /dev/null +++ b/html/changelogs/hellfirejag-psionic-sensitivity-refactor.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - rscadd: "Comprehensively reworked interactions between Psionics, Psi-Receivers, Mind Blankers, and Mindshields, such that they now all operate on a unified 'psi-sensitivity' and psi-blocking check. Being psionic makes you more psi-sensitive, but so does having a psi-receiver. Having a mindshield or mind blanker makes you less psi-sensitive. A variety of mechanics now operate on psi-sensitivity or relative sensitivity."