Files
Vanilla1040 92da873ec5 Positronic Brain Changes (#5764)
## About The Pull Request

This PR aims to change how positronic are handled and work, instead of
them being their standalone thing and you "dying" when its removed it
acts like a real positronic that you are confined to said positronic
even on gibbing, which can be moved from a cyborg to a synthetic shell
and back into said shell without much workarounds, RSD or anything else
annyoing, just as an example.

## Why It's Good For The Game

I think changing it to a behavior that is like a cyborgs positronic
makes overall more sense then the synthetics magically dying when their
positronic is removed, cyborgs can somehow exist and stay alive as a
positronic but synthetics cant?

## Proof Of Testing

Works on my machine

## Changelog

🆑
refactor: refactored how the synthetics brains work and behave
/🆑

---------

Co-authored-by: Artur Lang <24881678+Arturlang@users.noreply.github.com>
Co-authored-by: Mathilde <146444134+ibexgoetia@users.noreply.github.com>
2026-07-02 09:53:43 +02:00

127 lines
4.5 KiB
Plaintext

/mob/living/brain
var/obj/item/mmi/container = null
var/emp_damage = 0//Handles a type of MMI damage
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_LIVING
speech_span = SPAN_ROBOT
/mob/living/brain/Initialize(mapload)
. = ..()
create_dna(src)
stored_dna.initialize_dna(random_human_blood_type())
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
OB.brainmob = src
forceMove(OB)
if(!container?.mecha && (!container || container.immobilize)) //Unless inside a mecha, brains are rather helpless.
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED)
ADD_TRAIT(src, TRAIT_SILICON_EMOTES_ALLOWED, INNATE_TRAIT)
/mob/living/brain/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
//Bubber Edit Start
if(isnull(new_turf))
var/mob/living/carbon/brain_owner = null
if(istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/brain_loc = loc
brain_owner = brain_loc.owner
else if(istype(loc, /obj/item/mmi))
var/obj/item/mmi/mmi_loc = loc
if(istype(mmi_loc.loc, /obj/item/organ/brain))
var/obj/item/organ/brain/brain_loc = mmi_loc.loc
brain_owner = brain_loc.owner
if(brain_owner)
return ..(old_turf, get_turf(brain_owner), same_z_layer, notify_contents)
//Bubber Edit End
return ..()
/mob/living/brain/proc/create_dna()
stored_dna = new /datum/dna/stored(src)
if(!stored_dna.species)
var/rando_race = pick(get_selectable_species())
stored_dna.species = new rando_race()
/mob/living/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat != DEAD)
death(TRUE)
if(mind) //You aren't allowed to return to brains that don't exist
mind.set_current(null)
ghostize() //Ghostize checks for key so nothing else is necessary.
container = null
QDEL_NULL(stored_dna)
return ..()
/// Override parent here because... the blind message doesn't really work given what's happen when a brain suicides. Can't hear a brain going grey. So, we omit the "blind" message.
/mob/living/brain/send_applicable_messages()
visible_message(span_danger(get_visible_suicide_message()), span_userdanger(get_visible_suicide_message()))
/mob/living/brain/get_visible_suicide_message()
return "[src]'s brain is growing dull and lifeless. [p_They()] look[p_s()] like [p_theyve()] lost the will to live."
/mob/living/brain/apply_suicide_damage(obj/item/suicide_tool, damage_type = NONE) // we don't really care about applying damage to the brain mob and is just needless work.
return FALSE
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
return FALSE
/mob/living/brain/blob_act(obj/structure/blob/B)
return
/mob/living/brain/get_eye_protection()//no eyes
return FLASH_PROTECTION_WELDER
/mob/living/brain/get_ear_protection(ignore_deafness = FALSE)
return ..() + EAR_PROTECTION_HEAVY
/mob/living/brain/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, length = 25)
return // no eyes, no flashing
/mob/living/brain/can_be_revived()
if(!container || health <= HEALTH_THRESHOLD_DEAD)
return FALSE
return TRUE
/mob/living/brain/fully_replace_character_name(oldname,newname)
..()
if(stored_dna)
stored_dna.real_name = real_name
/mob/living/brain/forceMove(atom/destination)
if(container)
return container.forceMove(destination)
else if (istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/B = loc
B.forceMove(destination)
else if (istype(destination, /obj/item/organ/brain))
doMove(destination)
else if (istype(destination, /obj/item/mmi))
doMove(destination)
else
CRASH("Brainmob without a container [src] attempted to move to [destination].")
/mob/living/brain/update_mouse_pointer()
if (!client)
return
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
if(!container)
return
if (container.mecha)
var/obj/vehicle/sealed/mecha/M = container.mecha
if(M.mouse_pointer)
client.mouse_pointer_icon = M.mouse_pointer
/mob/living/brain/proc/get_traumas()
. = list()
if(istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/B = loc
. = B.traumas
/mob/living/brain/get_policy_keywords()
. = ..()
if(container)
. += "[container.type]"