Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] Cybernetic brains for androids #660

Merged
merged 1 commit into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading