Skip to content

Commit

Permalink
[MIRROR] Cybernetic brains for androids [MDB IGNORE] (#660)
Browse files Browse the repository at this point in the history
* Cybernetic brains for androids (#79421)

---------

Co-authored-by: SkyratBot <[email protected]>
Co-authored-by: GPeckman <[email protected]>
  • Loading branch information
3 people authored Nov 16, 2023
1 parent c9a9a13 commit 8d28706
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 37 deletions.
59 changes: 59 additions & 0 deletions code/modules/mob/living/brain/brain_cybernetic.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/obj/item/organ/internal/brain/cybernetic
name = "cybernetic brain"
desc = "A mechanical brain found inside of androids. Not to be confused with a positronic brain."
icon_state = "brain-c"
organ_flags = ORGAN_ROBOTIC | ORGAN_VITAL
failing_desc = "seems to be broken, and will not work without repairs."

/obj/item/organ/internal/brain/cybernetic/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 repair it with a <b>multitool</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 dents. You may be able to restore it with a <b>multitool</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.")

/obj/item/organ/internal/brain/cybernetic/check_for_repair(obj/item/item, mob/user)
if (item.tool_behaviour == TOOL_MULTITOOL) //attempt to repair the brain
if (brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
to_chat(user, span_warning("[src] is far too damaged, there's nothing else we can do for it!"))
return TRUE

if (DOING_INTERACTION(user, src))
to_chat(user, span_warning("you're already repairing [src]!"))
return TRUE

user.visible_message(span_notice("[user] slowly starts to repair [src] with [item]."), span_notice("You slowly start to repair [src] with [item]."))
var/did_repair = FALSE
while(damage > 0)
if(item.use_tool(src, user, 3 SECONDS, volume = 50))
did_repair = TRUE
set_organ_damage(max(0, damage - 20))
else
break

if (did_repair)
if (damage > 0)
user.visible_message(span_notice("[user] partially repairs [src] with [item]."), span_notice("You partially repair [src] with [item]."))
else
user.visible_message(span_notice("[user] fully repairs [src] with [item], causing its warning light to stop flashing."), span_notice("You fully repair [src] with [item], causing its warning light to stop flashing."))
else
to_chat(user, span_warning("You failed to repair [src] with [item]!"))

return TRUE
return FALSE

/obj/item/organ/internal/brain/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
switch(severity) // Hard cap on brain damage from EMP
if (EMP_HEAVY)
apply_organ_damage(20, BRAIN_DAMAGE_SEVERE)
if (EMP_LIGHT)
apply_organ_damage(10, BRAIN_DAMAGE_MILD)
78 changes: 41 additions & 37 deletions code/modules/mob/living/brain/brain_item.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@
// Brain size logic
transform = transform.Scale(brain_size)

/obj/item/organ/internal/brain/examine()
. = ..()
if(brain_size < 1)
. += span_notice("It is a bit on the smaller side...")
if(brain_size > 1)
. += span_notice("It is bigger than average...")

/obj/item/organ/internal/brain/Insert(mob/living/carbon/brain_owner, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
. = ..()
if(!.)
Expand Down Expand Up @@ -177,32 +170,17 @@
L.mind.transfer_to(brainmob)
to_chat(brainmob, span_notice("You feel slightly disoriented. That's normal when you're just a brain."))

/obj/item/organ/internal/brain/attackby(obj/item/O, mob/user, params)
/obj/item/organ/internal/brain/attackby(obj/item/item, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)

if(istype(O, /obj/item/borg/apparatus/organ_storage))
if(istype(item, /obj/item/borg/apparatus/organ_storage))
return //Borg organ bags shouldn't be killing brains

if(damage && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain
. = TRUE //don't do attack animation.
if(brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
to_chat(user, span_warning("[src] is far too damaged, there's nothing else we can do for it!"))
return

user.visible_message(span_notice("[user] starts to slowly pour the contents of [O] onto [src]."), span_notice("You start to slowly pour the contents of [O] onto [src]."))
if(!do_after(user, 3 SECONDS, src))
to_chat(user, span_warning("You failed to pour the contents of [O] onto [src]!"))
return

user.visible_message(span_notice("[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink."), span_notice("You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink."))
var/amount = O.reagents.get_reagent_amount(/datum/reagent/medicine/mannitol)
var/healto = max(0, damage - amount * 2)
O.reagents.remove_all(ROUND_UP(O.reagents.total_volume / amount * (damage - healto) * 0.5)) //only removes however much solution is needed while also taking into account how much of the solution is mannitol
set_organ_damage(healto) //heals 2 damage per unit of mannitol, and by using "set_organ_damage", we clear the failing variable if that was up
return
if (check_for_repair(item, user))
return TRUE

// Cutting out skill chips.
if(length(skillchips) && O.get_sharpness() == SHARP_EDGED)
if(length(skillchips) && item.get_sharpness() == SHARP_EDGED)
to_chat(user,span_notice("You begin to excise skillchips from [src]."))
if(do_after(user, 15 SECONDS, target = src))
for(var/chip in skillchips)
Expand All @@ -225,31 +203,57 @@
return

if(brainmob) //if we aren't trying to heal the brain, pass the attack onto the brainmob.
O.attack(brainmob, user) //Oh noooeeeee
item.attack(brainmob, user) //Oh noooeeeee

if(O.force != 0 && !(O.item_flags & NOBLUDGEON))
if(item.force != 0 && !(item.item_flags & NOBLUDGEON))
user.do_attack_animation(src)
playsound(loc, 'sound/effects/meatslap.ogg', 50)
set_organ_damage(maxHealth) //fails the brain as the brain was attacked, they're pretty fragile.
visible_message(span_danger("[user] hits [src] with [O]!"))
to_chat(user, span_danger("You hit [src] with [O]!"))
visible_message(span_danger("[user] hits [src] with [item]!"))
to_chat(user, span_danger("You hit [src] with [item]!"))

/obj/item/organ/internal/brain/proc/check_for_repair(obj/item/item, mob/user)
if(damage && item.is_drainable() && item.reagents.has_reagent(/datum/reagent/medicine/mannitol) && (organ_flags & ORGAN_ORGANIC)) //attempt to heal the brain
if(brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
to_chat(user, span_warning("[src] is far too damaged, there's nothing else we can do for it!"))
return TRUE

user.visible_message(span_notice("[user] starts to slowly pour the contents of [item] onto [src]."), span_notice("You start to slowly pour the contents of [item] onto [src]."))
if(!do_after(user, 3 SECONDS, src))
to_chat(user, span_warning("You failed to pour the contents of [item] onto [src]!"))
return TRUE

user.visible_message(span_notice("[user] pours the contents of [item] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink."), span_notice("You pour the contents of [item] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink."))
var/amount = item.reagents.get_reagent_amount(/datum/reagent/medicine/mannitol)
var/healto = max(0, damage - amount * 2)
item.reagents.remove_all(ROUND_UP(item.reagents.total_volume / amount * (damage - healto) * 0.5)) //only removes however much solution is needed while also taking into account how much of the solution is mannitol
set_organ_damage(healto) //heals 2 damage per unit of mannitol, and by using "set_organ_damage", we clear the failing variable if that was up
return TRUE
return FALSE

/obj/item/organ/internal/brain/examine(mob/user)
. = ..()
if(length(skillchips))
. += span_info("It has a skillchip embedded in it.")
. += brain_damage_examine()
if(brain_size < 1)
. += span_notice("It is a bit on the smaller side...")
if(brain_size > 1)
. += span_notice("It is bigger than average...")

/// Needed so subtypes can override examine text while still calling parent
/obj/item/organ/internal/brain/proc/brain_damage_examine()
if(suicided)
. += span_info("It's started turning slightly grey. They must not have been able to handle the stress of it all.")
return
return span_info("It's started turning slightly grey. 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)
. += 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>.")
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)
. += 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>.")
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
. += span_info("You can feel the small spark of life still left in this one.")
return span_info("You can feel the small spark of life still left in this one.")
else
. += span_info("This one is completely devoid of life.")
return span_info("This one is completely devoid of life.")

/obj/item/organ/internal/brain/attack(mob/living/carbon/C, mob/user)
if(!istype(C))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
meat = null
mutantbrain = /obj/item/organ/internal/brain/cybernetic
mutanttongue = /obj/item/organ/internal/tongue/robot
mutantstomach = null
mutantappendix = null
Expand Down
Binary file modified icons/obj/medical/organs/organs.dmi
Binary file not shown.
1 change: 1 addition & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -4767,6 +4767,7 @@
#include "code\modules\mob\living\basic\vermin\mouse.dm"
#include "code\modules\mob\living\basic\vermin\space_bat.dm"
#include "code\modules\mob\living\brain\brain.dm"
#include "code\modules\mob\living\brain\brain_cybernetic.dm"
#include "code\modules\mob\living\brain\brain_item.dm"
#include "code\modules\mob\living\brain\brain_say.dm"
#include "code\modules\mob\living\brain\death.dm"
Expand Down

0 comments on commit 8d28706

Please sign in to comment.