diff --git a/code/__DEFINES/research/anomalies.dm b/code/__DEFINES/research/anomalies.dm index e29254f8378..005045dbc26 100644 --- a/code/__DEFINES/research/anomalies.dm +++ b/code/__DEFINES/research/anomalies.dm @@ -1,18 +1,7 @@ -// Anomaly core types -/// Bluespace cores -#define ANOMALY_CORE_BLUESPACE /obj/item/assembly/signaler/anomaly/bluespace -/// Gravitational cores -#define ANOMALY_CORE_GRAVITATIONAL /obj/item/assembly/signaler/anomaly/grav -/// Flux -#define ANOMALY_CORE_FLUX /obj/item/assembly/signaler/anomaly/flux -/// Vortex -#define ANOMALY_CORE_VORTEX /obj/item/assembly/signaler/anomaly/vortex -/// Pyro -#define ANOMALY_CORE_PYRO /obj/item/assembly/signaler/anomaly/pyro - // Max amounts of cores you can make #define MAX_CORES_BLUESPACE 8 #define MAX_CORES_GRAVITATIONAL 8 #define MAX_CORES_FLUX 8 #define MAX_CORES_VORTEX 8 #define MAX_CORES_PYRO 8 +#define MAX_CORES_HALLUCINATION 8 diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm index afb2ee1b98c..23acca99409 100644 --- a/code/__DEFINES/supermatter.dm +++ b/code/__DEFINES/supermatter.dm @@ -94,6 +94,7 @@ #define GRAVITATIONAL_ANOMALY "gravitational_anomaly" #define FLUX_ANOMALY "flux_anomaly" #define PYRO_ANOMALY "pyro_anomaly" +#define HALLUCINATION_ANOMALY "hallucination_anomaly" #define VORTEX_ANOMALY "vortex_anomaly" //If integrity percent remaining is less than these values, the monitor sets off the relevant alarm. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index c233fdd87a8..f10f2fbf43c 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -380,7 +380,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai // You can stare into the abyss, but it does not stare back. // You're immune to the hallucination effect of the supermatter, either // through force of will, or equipment. Present on /mob or /datum/mind -#define TRAIT_SUPERMATTER_MADNESS_IMMUNE "supermatter_madness_immune" +#define TRAIT_MADNESS_IMMUNE "supermatter_madness_immune" // You can stare into the abyss, and it turns pink. // Being close enough to the supermatter makes it heal at higher temperatures diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 46651acfb69..b41b0b0ed45 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -48,11 +48,12 @@ SUBSYSTEM_DEF(research) var/list/created_anomaly_types = list() /// The hard limits of cores created for each anomaly type. For faster code lookup without switch statements. var/list/anomaly_hard_limit_by_type = list( - ANOMALY_CORE_BLUESPACE = MAX_CORES_BLUESPACE, - ANOMALY_CORE_PYRO = MAX_CORES_PYRO, - ANOMALY_CORE_GRAVITATIONAL = MAX_CORES_GRAVITATIONAL, - ANOMALY_CORE_VORTEX = MAX_CORES_VORTEX, - ANOMALY_CORE_FLUX = MAX_CORES_FLUX + /obj/item/assembly/signaler/anomaly/bluespace = MAX_CORES_BLUESPACE, + /obj/item/assembly/signaler/anomaly/pyro = MAX_CORES_PYRO, + /obj/item/assembly/signaler/anomaly/grav = MAX_CORES_GRAVITATIONAL, + /obj/item/assembly/signaler/anomaly/vortex = MAX_CORES_VORTEX, + /obj/item/assembly/signaler/anomaly/flux = MAX_CORES_FLUX, + /obj/item/assembly/signaler/anomaly/hallucination = MAX_CORES_HALLUCINATION, ) /// Lookup list for ordnance briefers. diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index a898e90fccc..c94fda750d6 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -419,4 +419,50 @@ if(EXPLODE_LIGHT) SSexplosions.lowturf += T +/obj/effect/anomaly/hallucination + name = "hallucination anomaly" + icon_state = "hallucination_anomaly" + aSignal = /obj/item/assembly/signaler/anomaly/hallucination + /// Time passed since the last effect, increased by delta_time of the SSobj + var/ticks = 0 + /// How many seconds between each small hallucination pulses + var/release_delay = 5 + +/obj/effect/anomaly/hallucination/anomalyEffect(delta_time) + . = ..() + ticks += delta_time + if(ticks < release_delay) + return + ticks -= release_delay + var/turf/open/our_turf = get_turf(src) + if(istype(our_turf)) + hallucination_pulse(our_turf, 5) + +/obj/effect/anomaly/hallucination/detonate() + var/turf/open/our_turf = get_turf(src) + if(istype(our_turf)) + hallucination_pulse(our_turf, 10) + +/obj/effect/anomaly/hallucination/proc/hallucination_pulse(turf/open/location, range) + for(var/mob/living/carbon/human/near in view(location, range)) + // If they are immune to hallucinations. + if (HAS_TRAIT(near, TRAIT_MADNESS_IMMUNE) || (near.mind && HAS_TRAIT(near.mind, TRAIT_MADNESS_IMMUNE))) + continue + + // Blind people don't get hallucinations. + if (near.is_blind()) + continue + + // Everyone else gets hallucinations. + var/dist = sqrt(1 / max(1, get_dist(near, location))) + near.hallucination += 50 * dist + near.hallucination = clamp(near.hallucination, 0, 150) + var/list/messages = list( + "You feel your conscious mind fall apart!", + "Reality warps around you!", + "Something's wispering around you!", + "You are going insane!", + ) + to_chat(near, span_warning(pick(messages))) + #undef ANOMALY_MOVECHANCE diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index dd3a904e422..96c867ef821 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -1352,6 +1352,16 @@ crate_name = "raw flux anomaly" crate_type = /obj/structure/closet/crate/secure/science +/datum/supply_pack/science/raw_hallucination_anomaly + name = "Raw Hallucination Anomaly" + desc = "The raw core of a hallucination anomaly, ready to be implosion-compressed into a powerful artifact." + cost = CARGO_CRATE_VALUE * 10 + access = ACCESS_ORDNANCE + access_view = ACCESS_ORDNANCE + contains = list(/obj/item/raw_anomaly_core/hallucination) + crate_name = "raw hallucination anomaly" + crate_type = /obj/structure/closet/crate/secure/science + /datum/supply_pack/science/raw_grav_anomaly name = "Raw Gravitational Anomaly" desc = "The raw core of a gravitational anomaly, ready to be implosion-compressed into a powerful artifact." diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 30b0e3badb2..453c7e34c6e 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -106,7 +106,7 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions." icon_state = "meson" inhand_icon_state = "meson" - clothing_traits = list(TRAIT_SUPERMATTER_MADNESS_IMMUNE) + clothing_traits = list(TRAIT_MADNESS_IMMUNE) darkness_view = 2 vision_flags = SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE @@ -541,7 +541,7 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE glass_colour_type = FALSE vision_flags = SEE_TURFS - clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_SUPERMATTER_MADNESS_IMMUNE) + clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_MADNESS_IMMUNE) var/list/hudlist = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED, DATA_HUD_SECURITY_ADVANCED) var/xray = FALSE diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 49a7130124e..df3bc20bfcb 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -11,6 +11,7 @@ /obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse, /obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla, /obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport, + /obj/effect/anomaly/hallucination = /obj/item/clothing/suit/armor/reactive/hallucinating, ) if(istype(weapon, /obj/item/assembly/signaler/anomaly)) @@ -323,3 +324,52 @@ reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return TRUE + +//Hallucinating + +/obj/item/clothing/suit/armor/reactive/hallucinating + name = "reactive hallucinating armor" + desc = "An experimental suit of armor with sensitive detectors hooked up to the mind of the wearer, sending mind pulses that causes hallucinations around you." + cooldown_message = span_danger("The connection is currently out of sync... Recalibrating.") + emp_message = span_warning("You feel the backsurge of a mind pulse.") + var/range = 3 + +/obj/item/clothing/suit/armor/reactive/hallucinating/dropped(mob/user) + ..() + if(istype(user)) + REMOVE_TRAIT(user, TRAIT_MADNESS_IMMUNE, "reactive_hallucinating_armor") + +/obj/item/clothing/suit/armor/reactive/hallucinating/equipped(mob/user, slot) + ..() + if(slot_flags & slot) //Was equipped to a valid slot for this item? + ADD_TRAIT(user, TRAIT_MADNESS_IMMUNE, "reactive_hallucinating_armor") + +/obj/item/clothing/suit/armor/reactive/hallucinating/cooldown_activation(mob/living/carbon/human/owner) + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + sparks.set_up(1, 1, src) + sparks.start() + ..() + +/obj/item/clothing/suit/armor/reactive/hallucinating/reactive_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + owner.visible_message(span_danger("[src] blocks [attack_text], sending out mental pulses!")) + hallucination_pulse(owner) + return TRUE + +/obj/item/clothing/suit/armor/reactive/hallucinating/emp_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + owner.visible_message(span_danger("[src] blocks [attack_text], but pulls a massive charge of mental energy into [owner] from the surrounding environment!")) + owner.hallucination += 25 + owner.hallucination = clamp(owner.hallucination, 0, 150) + reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration + return TRUE + +/obj/item/clothing/suit/armor/reactive/hallucinating/proc/hallucination_pulse(mob/living/carbon/human/owner) + var/turf/location = get_turf(owner) + for(var/mob/living/carbon/human/near in view(location, range)) + // If they are immune to hallucinations. + if (HAS_TRAIT(near, TRAIT_MADNESS_IMMUNE) || (near.mind && HAS_TRAIT(near.mind, TRAIT_MADNESS_IMMUNE))) + continue + + // Everyone else gets hallucinations. + var/dist = sqrt(1 / max(1, get_dist(near, location))) + near.hallucination += 25 * dist + near.hallucination = clamp(near.hallucination, 0, 150) diff --git a/code/modules/events/anomaly_hallucination.dm b/code/modules/events/anomaly_hallucination.dm new file mode 100644 index 00000000000..0f3628c7e0b --- /dev/null +++ b/code/modules/events/anomaly_hallucination.dm @@ -0,0 +1,15 @@ +/datum/round_event_control/anomaly/anomaly_hallucination + name = "Anomaly: Hallucination" + typepath = /datum/round_event/anomaly/anomaly_hallucination + + min_players = 10 + max_occurrences = 5 + weight = 20 + +/datum/round_event/anomaly/anomaly_hallucination + startWhen = 10 + announceWhen = 3 + anomaly_path = /obj/effect/anomaly/hallucination + +/datum/round_event/anomaly/anomaly_hallucination/announce(fake) + priority_announce("Hallucinatory event hitting the station. Expected location: [impact_area.name].", "Anomaly Alert") diff --git a/code/modules/library/skill_learning/job_skillchips/psychologist.dm b/code/modules/library/skill_learning/job_skillchips/psychologist.dm index 280bc43aa0d..6450d13b89a 100644 --- a/code/modules/library/skill_learning/job_skillchips/psychologist.dm +++ b/code/modules/library/skill_learning/job_skillchips/psychologist.dm @@ -1,7 +1,7 @@ /obj/item/skillchip/job/psychology name = "HYPERG1G4 skillchip" desc = "Learn to bend the abyss to your will." - auto_traits = list(TRAIT_SUPERMATTER_SOOTHER, TRAIT_SUPERMATTER_MADNESS_IMMUNE) + auto_traits = list(TRAIT_SUPERMATTER_SOOTHER, TRAIT_MADNESS_IMMUNE) skill_name = "Supermatter Cognition Theory" skill_description = "Understand the correct mental patterns to keep in mind around matter in a hyperfractal state, causing immunity to visions and making the matter in question \"calmer\"." skill_icon = "spa" diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm index 740489b5645..a68293bd1b4 100644 --- a/code/modules/mod/modules/modules_visor.dm +++ b/code/modules/mod/modules/modules_visor.dm @@ -73,7 +73,7 @@ technology, used by construction workers and miners across the galaxy to see basic structural and terrain layouts \ through walls, regardless of lighting conditions. They say these also let you see behind you." icon_state = "meson_visor" - visor_traits = list(TRAIT_MESON_VISION, TRAIT_SUPERMATTER_MADNESS_IMMUNE) + visor_traits = list(TRAIT_MESON_VISION, TRAIT_MADNESS_IMMUNE) //Thermal Visor /obj/item/mod/module/visor/thermal diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 6554abc0ba0..a3f08bf88f6 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -304,7 +304,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/examine(mob/user) . = ..() - var/immune = HAS_TRAIT(user, TRAIT_SUPERMATTER_MADNESS_IMMUNE) || (user.mind && HAS_TRAIT(user.mind, TRAIT_SUPERMATTER_MADNESS_IMMUNE)) + var/immune = HAS_TRAIT(user, TRAIT_MADNESS_IMMUNE) || (user.mind && HAS_TRAIT(user.mind, TRAIT_MADNESS_IMMUNE)) if(isliving(user) && !immune && (get_dist(user, src) < HALLUCINATION_RANGE(power))) . += span_danger("You get headaches just from looking at it.") @@ -521,12 +521,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return switch(type) if(FLUX_ANOMALY) - var/obj/effect/anomaly/flux/flux = new(local_turf, has_changed_lifespan ? 300 : null, FALSE) + var/obj/effect/anomaly/flux/flux = new(local_turf, has_changed_lifespan ? rand(250, 350) : null, FALSE) flux.explosive = !has_changed_lifespan if(GRAVITATIONAL_ANOMALY) - new /obj/effect/anomaly/grav(local_turf, has_changed_lifespan ? 250 : null, FALSE) + new /obj/effect/anomaly/grav(local_turf, has_changed_lifespan ? rand(200, 300) : null, FALSE) if(PYRO_ANOMALY) - new /obj/effect/anomaly/pyro(local_turf, has_changed_lifespan ? 200 : null, FALSE) + new /obj/effect/anomaly/pyro(local_turf, has_changed_lifespan ? rand(150, 250) : null, FALSE) + if(HALLUCINATION_ANOMALY) + new /obj/effect/anomaly/hallucination(local_turf, has_changed_lifespan ? rand(150, 250) : null, FALSE) if(VORTEX_ANOMALY) new /obj/effect/anomaly/bhole(local_turf, 20, FALSE) diff --git a/code/modules/power/supermatter/supermatter_delamination.dm b/code/modules/power/supermatter/supermatter_delamination.dm index 6dd967dcab1..11b02e4d473 100644 --- a/code/modules/power/supermatter/supermatter_delamination.dm +++ b/code/modules/power/supermatter/supermatter_delamination.dm @@ -13,7 +13,7 @@ spawn_anomalies() /datum/supermatter_delamination/proc/spawn_anomalies() - var/list/anomaly_types = list(FLUX_ANOMALY = 75, GRAVITATIONAL_ANOMALY = 55, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1) + var/list/anomaly_types = list(FLUX_ANOMALY = 65, GRAVITATIONAL_ANOMALY = 55, HALLUCINATION_ANOMALY = 45, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1) var/list/anomaly_places = GLOB.generic_event_spawns var/currently_spawning_anomalies = round(anomalies_to_spawn * 0.5, 1) anomalies_to_spawn -= currently_spawning_anomalies @@ -26,7 +26,7 @@ /datum/supermatter_delamination/proc/spawn_overtime() - var/list/anomaly_types = list(FLUX_ANOMALY = 75, GRAVITATIONAL_ANOMALY = 55, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1) + var/list/anomaly_types = list(FLUX_ANOMALY = 65, GRAVITATIONAL_ANOMALY = 55, HALLUCINATION_ANOMALY = 45, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1) var/list/anomaly_places = GLOB.generic_event_spawns var/current_spawn = rand(5 SECONDS, 10 SECONDS) diff --git a/code/modules/power/supermatter/supermatter_process.dm b/code/modules/power/supermatter/supermatter_process.dm index 3dfc5e0027f..796f6b5de4a 100644 --- a/code/modules/power/supermatter/supermatter_process.dm +++ b/code/modules/power/supermatter/supermatter_process.dm @@ -316,7 +316,7 @@ psy_overlay = TRUE // If they are immune to supermatter hallucinations. - if (HAS_TRAIT(seen_by_sm, TRAIT_SUPERMATTER_MADNESS_IMMUNE) || (seen_by_sm.mind && HAS_TRAIT(seen_by_sm.mind, TRAIT_SUPERMATTER_MADNESS_IMMUNE))) + if (HAS_TRAIT(seen_by_sm, TRAIT_MADNESS_IMMUNE) || (seen_by_sm.mind && HAS_TRAIT(seen_by_sm.mind, TRAIT_MADNESS_IMMUNE))) continue // Blind people don't get supermatter hallucinations. @@ -370,6 +370,8 @@ if(prob(5)) supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10)) + if(prob(5)) + supermatter_anomaly_gen(src, HALLUCINATION_ANOMALY, rand(5, 10)) if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(5) || prob(1)) supermatter_anomaly_gen(src, GRAVITATIONAL_ANOMALY, rand(5, 10)) if((power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2)) || (prob(0.3) && power > POWER_PENALTY_THRESHOLD)) diff --git a/code/modules/research/anomaly/anomaly_core.dm b/code/modules/research/anomaly/anomaly_core.dm index 9b914175448..bf4f7a357f8 100644 --- a/code/modules/research/anomaly/anomaly_core.dm +++ b/code/modules/research/anomaly/anomaly_core.dm @@ -61,3 +61,9 @@ desc = "The neutralized core of a vortex anomaly. It won't sit still, as if some invisible force is acting on it. It'd probably be valuable for research." icon_state = "vortex_core" anomaly_type = /obj/effect/anomaly/bhole + +/obj/item/assembly/signaler/anomaly/hallucination + name = "\improper hallucination anomaly core" + desc = "The neutralized core of a hallucination anomaly. It seems to be moving, but it's probably your imagination. It'd probably be valuable for research." + icon_state = "hallucination_core" + anomaly_type = /obj/effect/anomaly/hallucination diff --git a/code/modules/research/anomaly/raw_anomaly.dm b/code/modules/research/anomaly/raw_anomaly.dm index 0648bd1912a..e936292fc97 100644 --- a/code/modules/research/anomaly/raw_anomaly.dm +++ b/code/modules/research/anomaly/raw_anomaly.dm @@ -45,6 +45,12 @@ anomaly_type = /obj/item/assembly/signaler/anomaly/flux icon_state = "rawcore_flux" +/obj/item/raw_anomaly_core/hallucination + name = "raw hallucination core" + desc = "The raw core of a hallucination anomaly, makes your head spin." + anomaly_type = /obj/item/assembly/signaler/anomaly/hallucination + icon_state = "rawcore_hallucination" + /obj/item/raw_anomaly_core/random name = "random raw core" desc = "You should not see this!" diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index bec2d6e7c89..a88b88be2ee 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/obj/assemblies/new_assemblies.dmi b/icons/obj/assemblies/new_assemblies.dmi index 689fa3f201f..35484aa9613 100644 Binary files a/icons/obj/assemblies/new_assemblies.dmi and b/icons/obj/assemblies/new_assemblies.dmi differ diff --git a/modular_skyrat/modules/customization/modules/clothing/glasses/hud.dm b/modular_skyrat/modules/customization/modules/clothing/glasses/hud.dm index b2d3c741957..b54cc98ee7a 100644 --- a/modular_skyrat/modules/customization/modules/clothing/glasses/hud.dm +++ b/modular_skyrat/modules/customization/modules/clothing/glasses/hud.dm @@ -27,7 +27,7 @@ name = "mesons eyepatch HUD" desc = "For those that only want to go half insane when staring at the supermatter." icon_state = "mesonpatch" - clothing_traits = list(TRAIT_SUPERMATTER_MADNESS_IMMUNE) + clothing_traits = list(TRAIT_MADNESS_IMMUNE) darkness_view = 2 vision_flags = SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE