[TM ready, again] brain augment fluff (#2497)

## About The Pull Request

...this time it should actually have been based correctly. As per [my
previous pr](https://github.com/Bubberstation/Bubberstation/pull/2492).
I know half the code was done in skyrat but this isn't really the type
of PR which can be modularized neatly anyways. Sorry. Anyways, it's done
now.

As for the empathic sensor, that is an item done by request and probably
could be worth higher cost? Now it's removed from roundstart.

## Proof Of Testing
don't mind the world of warcraft noises. I'm not sure why those picked
up. On the floor in the videos you can also see the new vox brain, the
new cortically-augmented brain, and the unchanged android brain.

The experiment works right

https://github.com/user-attachments/assets/2a542499-30ad-4848-b415-1a836d25bfcf
Empathic sensor reads and sends. It no longer is read/send by/to
shadekin, using its own "frequency"

https://github.com/user-attachments/assets/00552f32-829e-4efc-9c2d-0314d8ea0e2e

Removed, but the selection dropdown is there. Just empty.

![Screenshot_3](https://github.com/user-attachments/assets/2e1ad9bf-1da8-4307-946f-aa775e94f776)
Actually 0 now

![Screenshot_2](https://github.com/user-attachments/assets/2b05064f-136f-4102-8c35-81248d298056)
https://github.com/Bubberstation/Bubberstation/issues/2724 is actually
resolved

https://github.com/user-attachments/assets/18b8185c-5e2e-4927-afeb-f06c1887b5c3

## Changelog

🆑
code: "Brain augment" and "Brain implant" selection in prefs
add: Added new brain type for humans. It's chrome, choom
add: One new brain implant for civilian use, the empathic sensor.
balance: androids get a brain damage cap var (999); can't be EMP'd while
already dead; alert texts when they're EMP'd
image: new sprite for vox brain
code: vox (primalis) brain now a child of android brains
/🆑

---------

Co-authored-by: Waterpig <49160555+Majkl-J@users.noreply.github.com>
This commit is contained in:
aKromatopzia
2025-01-12 13:23:30 -08:00
committed by GitHub
co-authored by Waterpig
parent 8053b953d6
commit 25a23cd8b3
16 changed files with 274 additions and 37 deletions
@@ -11,6 +11,7 @@
#define AUGMENT_SLOT_R_LEG "Right Leg"
//Organs
#define AUGMENT_CATEGORY_ORGANS "Organs"
#define AUGMENT_SLOT_BRAIN "Brain"
#define AUGMENT_SLOT_HEART "Heart"
#define AUGMENT_SLOT_LUNGS "Lungs"
#define AUGMENT_SLOT_LIVER "Liver"
@@ -4,6 +4,9 @@
icon_state = "brain-c"
organ_flags = ORGAN_ROBOTIC | ORGAN_VITAL
failing_desc = "seems to be broken, and will not work without repairs."
var/emp_dmg_mult = 1 //BUBBER EDIT - Variable multiplier for damage from EMPs. Note the base damage is 20.
var/emp_dmg_max = 999 ///BUBBER EDIT - Threshold before the organ simply stops taking damage from EMPs. Defaults to kill
/obj/item/organ/internal/brain/cybernetic/brain_damage_examine()
if(suicided)
@@ -52,8 +55,15 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
switch(severity) // Hard cap on brain damage from EMP
//BUBBER EDIT BEGIN - can't be emp'd if dead
if(owner.stat == DEAD)
return
//BUBBER EDIT END
switch(severity)
if (EMP_HEAVY)
apply_organ_damage(20, BRAIN_DAMAGE_SEVERE)
to_chat(owner, span_boldwarning("You feel [pick("like your brain is being fried", "a sharp pain in your head")]!")) //BUBBER EDIT - added alert text for getting EMP'd.
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (20*emp_dmg_mult), emp_dmg_max) //BUBBER EDIT - cap implemented
if (EMP_LIGHT)
apply_organ_damage(10, BRAIN_DAMAGE_MILD)
to_chat(owner, span_warning("You feel [pick("disoriented", "confused", "dizzy")].")) //BUBBER EDIT - added alert text for getting EMP'd.
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (10*emp_dmg_mult), emp_dmg_max) //BUBBER EDIT - cap implemented
@@ -25,12 +25,14 @@
)
var/list/organs_to_process = list(
"brain" = "Brain", //BUBBER EDIT
"heart" = "Heart",
"lungs" = "Lungs",
"liver" = "Liver",
"stomach" = "Stomach",
"eyes" = "Eyes",
"tongue" = "Tongue",
"Brain implant" = "Brain implant", //BUBBER EDIT
"Mouth implant" = "Mouth implant",
"Left Arm implant" = "Left Arm implant",
"Right Arm implant" = "Right Arm implant",
Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

@@ -13,7 +13,7 @@
)
inherent_biotypes = MOB_ORGANIC | MOB_HUMANOID
mutantlungs = /obj/item/organ/internal/lungs/nitrogen/vox
mutantbrain = /obj/item/organ/internal/brain/vox
mutantbrain = /obj/item/organ/internal/brain/cybernetic/cortical/vox //BUBBER EDIT - new brain dropped
breathid = "n2"
mutant_bodyparts = list()
meat = /obj/item/food/meat/slab/chicken/human //item file in teshari module
@@ -6,9 +6,41 @@
return
var/obj/item/organ/organ_path = path // cast this to an organ so we can get the slot from it using initial()
var/obj/item/organ/new_organ = new path()
new_organ.copy_traits_from(human_holder.get_organ_slot(initial(organ_path.slot)))
new_organ.Insert(human_holder, special = TRUE, movement_flags = DELETE_IF_REPLACED)
if(slot == AUGMENT_SLOT_BRAIN)
var/obj/item/organ/internal/brain/old_brain = human_holder.get_organ_slot(ORGAN_SLOT_BRAIN)
var/obj/item/organ/internal/brain/new_brain = new organ_path()
var/datum/mind/holder_mind = human_holder.mind
new_brain.modular_persistence = old_brain.modular_persistence
old_brain.modular_persistence = null
new_brain.copy_traits_from(old_brain)
new_brain.Insert(human_holder, special = TRUE)
old_brain.moveToNullspace() //for some reason it doesn't want to be deleted. So I'm using this hack method until it can be figured out why. But, it works!
STOP_PROCESSING(SSobj, old_brain)
if(!holder_mind)
return
holder_mind.transfer_to(human_holder, TRUE)
else
var/obj/item/organ/new_organ = new path()
new_organ.copy_traits_from(human_holder.get_organ_slot(initial(organ_path.slot)))
new_organ.Insert(human_holder, special = TRUE, movement_flags = DELETE_IF_REPLACED)
//BUBBER EDIT - New brain
//BRAINS
/datum/augment_item/organ/brain
slot = AUGMENT_SLOT_BRAIN
/datum/augment_item/organ/brain/cortical
name = "Cortically-Augmented Brain"
slot = AUGMENT_SLOT_BRAIN
path = /obj/item/organ/internal/brain/cybernetic/cortical
//EDIT END
//HEARTS
/datum/augment_item/organ/heart
@@ -13,7 +13,7 @@
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
mutanttongue = /obj/item/organ/internal/tongue/vox
mutantlungs = /obj/item/organ/internal/lungs/nitrogen/vox
mutantbrain = /obj/item/organ/internal/brain/vox
mutantbrain = /obj/item/organ/internal/brain/cybernetic/cortical/vox
breathid = "n2"
mutant_bodyparts = list()
payday_modifier = 1.0
@@ -18,26 +18,3 @@
cold_level_3_threshold = 0
organ_flags = ORGAN_ROBOTIC
/obj/item/organ/internal/brain/vox
name = "vox brain"
organ_flags = ORGAN_ROBOTIC
/obj/item/organ/internal/brain/vox/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(owner.stat == DEAD)
return
switch(severity)
if(1)
to_chat(owner, span_boldwarning("You feel [pick("like your brain is being fried", "a sharp pain in your head")]!"))
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20, 150)
owner.set_jitter_if_lower(30 SECONDS)
owner.adjust_stutter(30 SECONDS)
owner.adjust_confusion(10 SECONDS)
if(2)
to_chat(owner, span_warning("You feel [pick("disoriented", "confused", "dizzy")]."))
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 150)
owner.set_jitter_if_lower(30 SECONDS)
owner.adjust_stutter(30 SECONDS)
owner.adjust_confusion(3 SECONDS)
@@ -0,0 +1,98 @@
#define LANGUAGE_IMPLANT "implant"
/obj/item/organ/internal/cyberimp/brain/empathic_sensor
name = "empathic sensor implant"
desc = "This won't fix your social issues, but it may help you repress them better." //not final
icon_state = "brain_implant_antidrop"
var/active = FALSE
var/list/stored_items = list()
slot = ORGAN_SLOT_BRAIN_CEREBELLUM
var/modifies_speech = TRUE
// This should appropriately grant and remove empathy from the implant - important if you are a shadekin for some reason to not remove native languages, and allow the procs to work
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/emp_act(severity)
. = ..()
if((organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF)
return
organ_flags |= ORGAN_FAILING
UnregisterSignal(owner, COMSIG_MOB_SAY)
owner.remove_language(/datum/language/marish/empathy, source = LANGUAGE_IMPLANT)
addtimer(CALLBACK(src, PROC_REF(reboot)), 180 / severity)
to_chat(owner, span_warning("You feel overwhelmed!"))
switch(severity)
if (EMP_HEAVY)
owner.adjust_stutter(180 SECONDS)
owner.adjust_silence(30 SECONDS)
if (EMP_LIGHT)
owner.adjust_stutter(90 SECONDS)
owner.adjust_silence(10 SECONDS)
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/proc/implant_ready()
RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
owner.grant_language(/datum/language/marish/empathy, source = LANGUAGE_IMPLANT)
to_chat(owner, span_abductor("Your mind opens to others. You can hear the thoughts of those around you, but only faintly."))
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/on_mob_remove(mob/living/carbon/implant_owner)
. = ..()
organ_flags &= ~ORGAN_FAILING
UnregisterSignal(implant_owner, COMSIG_MOB_SAY)
implant_owner.remove_language(/datum/language/marish/empathy, source = LANGUAGE_IMPLANT)
if(QDELETED(src))
return
to_chat(implant_owner, span_abductor("Your mind closes from others. It's quiet, now."))
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/on_mob_insert(mob/living/carbon/receiver)
. = ..()
to_chat(receiver, span_abductor("You begin to feel an awareness of those around you."))
addtimer(CALLBACK(src, PROC_REF(implant_ready)), 90)
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/proc/reboot()
organ_flags &= ~ORGAN_FAILING
implant_ready()
//code mostly lifted from shadekins
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/proc/modify_speech(datum/source, list/speech_args)
ASYNC
if(organ_flags & ORGAN_FAILING) //just in case they somehow activate this while the implant is disabled...
to_chat(owner, span_abductor("You are unable to project your thoughts."))
return
actually_modify_speech(source, speech_args)
speech_args[SPEECH_MESSAGE] = "" // Makes it not send to chat verbally
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/proc/handle_speech(datum/source, list/speech_args)
if(speech_args[SPEECH_LANGUAGE] == /datum/language/marish/empathy)
return modify_speech(source, speech_args)
//I couldnt get this to work as a TYPE_PROC_REF. So it's copied.
/obj/item/organ/internal/cyberimp/brain/empathic_sensor/proc/actually_modify_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
var/mob/living/carbon/human/user = source
var/obj/item/organ/internal/ears/shadekin/user_ears = user.get_organ_slot(ORGAN_SLOT_EARS)
var/mode = istype(user_ears)
user.balloon_alert_to_viewers("[mode ? "ears vibrate" : "shivers"]", "projecting thoughts...")
if(!do_after(source, 2 SECONDS, source))
message = full_capitalize(rot13(message))
var/rendered = span_abductor("<b>[user.real_name]:</b> [message]")
user.log_talk(message, LOG_SAY, tag="empathic-sensor")
for(var/mob/living/carbon/human/living_mob in GLOB.alive_mob_list)
var/obj/item/organ/internal/ears/shadekin/target_ears = living_mob.get_organ_slot(ORGAN_SLOT_EARS)
var/obj/item/organ/internal/cyberimp/brain/empathic_sensor/target_implant = living_mob.get_organ_slot(ORGAN_SLOT_BRAIN_CEREBELLUM)
if(!istype(target_implant))
continue
to_chat(living_mob, rendered)
if(living_mob != user)
mode = istype(target_ears)
living_mob.balloon_alert_to_viewers("[mode ? "ears vibrate" : "shivers"]", "transmission heard...")
if(length(GLOB.dead_mob_list))
for(var/mob/dead_mob in GLOB.dead_mob_list)
if(dead_mob.client)
var/link = FOLLOW_LINK(dead_mob, user)
to_chat(dead_mob, "[link] [rendered]")
@@ -0,0 +1,55 @@
//Unifying vox brains and android brains, so that when one is updated the other is as well.
//The accessible cybernetic brain
/obj/item/organ/internal/brain/cybernetic/cortical
name = "cortically-augmented brain"
desc = "A brain which has been in some part mechanized."
icon = 'modular_skyrat/master_files/icons/obj/medical/organs/organs.dmi'
icon_state = "brain-c"
emp_dmg_mult = 1.5 //Note that the base damage is 20/10
emp_dmg_max = 150
//Extra effects
/obj/item/organ/internal/brain/cybernetic/cortical/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(owner.stat == DEAD)
return
switch(severity)
if(1)
owner.set_jitter_if_lower(30 SECONDS)
owner.adjust_stutter(30 SECONDS)
owner.adjust_confusion(10 SECONDS)
if(2)
owner.set_jitter_if_lower(15 SECONDS)
owner.adjust_stutter(15 SECONDS)
owner.adjust_confusion(3 SECONDS)
// It's still organic
/obj/item/organ/internal/brain/cybernetic/cortical/brain_damage_examine()
if(suicided)
return span_info("Its circuitry is smoking slightly. They must not have been able to handle the stress of it all.")
if(brainmob && (decoy_override || brainmob.client || brainmob.get_ghost()))
if(organ_flags & ORGAN_FAILING)
return span_info("It seems to still have a bit of energy within it, but it's rather damaged... You may be able to restore it with some <b>mannitol</b>.")
else if(damage >= BRAIN_DAMAGE_DEATH*0.5)
return span_info("You can feel the small spark of life still left in this one, but it's got some bruises. You may be able to restore it with some <b>mannitol</b>.")
else
return span_info("You can feel the small spark of life still left in this one.")
else
return span_info("This one is completely devoid of life.")
//New vox Brain
/obj/item/organ/internal/brain/cybernetic/cortical/vox
name = "vox-augmented brain"
desc = "A brain which has been in some part mechanized. The components are seamlessly integrated into the flesh."
emp_dmg_mult = 1 //Nobody notices the brain damage anyways wink wink
//surplus; TBI to prosthetic organ quirk
/obj/item/organ/internal/brain/cybernetic/cortical/surplus
name = "surplus augmented brain"
desc = "A brain which has been in some part mechanized. It looks a bit cheap."
maxHealth = BRAIN_DAMAGE_DEATH*0.5 //200 -> 100, at time of creation
emp_dmg_max = 999
@@ -1 +1,2 @@
#define TECHWEB_NODE_INTERDYNE "interdyne_tech"
#define TECHWEB_NODE_EMPATHY_IMPLANT "empathy_implant"
@@ -0,0 +1,26 @@
//scan shadekin
/datum/experiment/scanning/people/open_minds
name = "Human Field Research: Connected Minds"
description = "We need data on the effects of extra-sensory communication in organisms. Scan some samples of humanoid organisms which can think out loud."
performance_hint = "Such capabilities can be induced with genetic infusion, or finding the right person."
required_traits_desc = "extra-sensory communication"
required_count = 2
/datum/experiment/scanning/people/open_minds/is_valid_scan_target(mob/living/carbon/human/check)
. = ..()
if (!.)
return
//check for genetics telepathy
if(check.dna.check_mutation(/datum/mutation/human/telepathy))
return TRUE
//check for shadekin organs
var/obj/item/organ/internal/ears/shadekin/ears = check.get_organ_slot(ORGAN_SLOT_EARS)
var/obj/item/organ/internal/tongue/shadekin/tongue = check.get_organ_slot(ORGAN_SLOT_TONGUE)
if(istype(ears) || istype(tongue))
return TRUE
return FALSE
@@ -46,8 +46,6 @@
if(speech_args[SPEECH_LANGUAGE] in languages_native) // Speaking a native language?
return modify_speech(source, speech_args)
/obj/item/organ/internal/tongue/shadekin/modify_speech(datum/source, list/speech_args)
ASYNC
actually_modify_speech(source, speech_args)
@@ -56,7 +54,9 @@
/obj/item/organ/internal/tongue/shadekin/proc/actually_modify_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
var/mob/living/carbon/human/user = source
user.balloon_alert_to_viewers("ears vibrate", "projecting thoughts...")
var/obj/item/organ/internal/ears/shadekin/user_ears = user.get_organ_slot(ORGAN_SLOT_EARS)
var/mode = istype(user_ears)
user.balloon_alert_to_viewers("[mode ? "ears vibrate" : "shivers"]", "projecting thoughts...")
if(!do_after(source, 2 SECONDS, source))
message = full_capitalize(rot13(message))
@@ -64,12 +64,15 @@
user.log_talk(message, LOG_SAY, tag="shadekin")
for(var/mob/living/carbon/human/living_mob in GLOB.alive_mob_list)
var/obj/item/organ/internal/ears/shadekin/ears = living_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(!istype(ears))
var/obj/item/organ/internal/ears/shadekin/target_ears = living_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(!istype(target_ears))
continue
to_chat(living_mob, rendered)
if(living_mob != user)
living_mob.balloon_alert_to_viewers("ears vibrate", "transmission heard...")
mode = istype(target_ears)
living_mob.balloon_alert_to_viewers("[mode ? "ears vibrate" : "shivers"]", "transmission heard...")
if(length(GLOB.dead_mob_list))
for(var/mob/dead_mob in GLOB.dead_mob_list)
@@ -9,3 +9,20 @@
RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_MEDICAL
)
departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
/datum/design/empathic_sensor
name = "Empathic sensor implant"
desc = "An implant which allows one to intuit the thoughts of some."
id = "ci_empathic_sensor"
build_type = PROTOLATHE | MECHFAB
materials = list(
/datum/material/iron = SMALL_MATERIAL_AMOUNT * 6,
/datum/material/glass = SMALL_MATERIAL_AMOUNT * 6,
/datum/material/silver = HALF_SHEET_MATERIAL_AMOUNT,
/datum/material/gold = HALF_SHEET_MATERIAL_AMOUNT,
/datum/material/bluespace = SHEET_MATERIAL_AMOUNT,)
build_path = /obj/item/organ/internal/cyberimp/brain/empathic_sensor
category = list(
RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_UTILITY
)
departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE
@@ -1,5 +1,17 @@
// RESEARCH NODES
/datum/techweb_node/cyber/empathy_implant
id = TECHWEB_NODE_EMPATHY_IMPLANT
display_name = "Empathic Sensor Implant"
description = "The result of assuredly-ethical experiments conducted on those with special minds."
prereq_ids = list(TECHWEB_NODE_CYBER_IMPLANTS)
design_ids = list(
"ci_empathic_sensor",
)
required_experiments = list(/datum/experiment/scanning/people/open_minds)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS)
announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL)
/datum/techweb_node/botanygene
id = TECHWEB_NODE_BOTANY_ADV
display_name = "Experimental Botanical Engineering"
+3
View File
@@ -7792,6 +7792,7 @@
#include "modular_skyrat\modules\icspawning\code\spell.dm"
#include "modular_skyrat\modules\icspawning\code\standard.dm"
#include "modular_skyrat\modules\implants\code\augments_arms.dm"
#include "modular_skyrat\modules\implants\code\augments_brain.dm"
#include "modular_skyrat\modules\implants\code\augments_chest.dm"
#include "modular_skyrat\modules\implants\code\augments_eyes.dm"
#include "modular_skyrat\modules\implants\code\augments_internal.dm"
@@ -8312,6 +8313,7 @@
#include "modular_skyrat\modules\opposing_force\code\equipment\modsuit.dm"
#include "modular_skyrat\modules\opposing_force\code\equipment\spells.dm"
#include "modular_skyrat\modules\opposing_force\code\equipment\uplink.dm"
#include "modular_skyrat\modules\organs\code\brain.dm"
#include "modular_skyrat\modules\organs\code\ears.dm"
#include "modular_skyrat\modules\organs\code\heart.dm"
#include "modular_skyrat\modules\organs\code\liver.dm"
@@ -9057,6 +9059,7 @@
#include "modular_zubbers\code\modules\events\scrubber_overflow.dm"
#include "modular_zubbers\code\modules\events\ghost_role\blob.dm"
#include "modular_zubbers\code\modules\experisci\handheld_scanner.dm"
#include "modular_zubbers\code\modules\experisci\experiment\experiments.dm"
#include "modular_zubbers\code\modules\experisci\experiment\handlers\experiment_handler.dm"
#include "modular_zubbers\code\modules\experisci\experiment\types\scanning_fish.dm"
#include "modular_zubbers\code\modules\fishing\fishing_minigame.dm"