diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 0fb95f6c22d..a0168448391 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -12,91 +12,112 @@ var/alien = 0 var/syndiemmi = 0 //Whether or not this is a Syndicate MMI var/mob/living/carbon/brain/brainmob = null//The current occupant. + var/obj/item/organ/brain/held_brain = null // This is so MMI's aren't brainscrubber 9000's var/mob/living/silicon/robot/robot = null//Appears unused. var/obj/mecha/mecha = null//This does not appear to be used outside of reference in mecha.dm. // I'm using this for mechs giving MMIs HUDs now - attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/organ/internal/brain/crystal )) - user << " This brain is too malformed to be able to use with the [src]." +/obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + if(istype(O, /obj/item/organ/brain/crystal )) + user << " This brain is too malformed to be able to use with the [src]." + return + if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO + var/obj/item/organ/brain/B = O + if(!B.brainmob) + user << "You aren't sure where this brain came from, but you're pretty sure it's a useless brain." return - if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO - if(!O:brainmob) - user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain." - return - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] sticks \a [O] into \the [src].")) - brainmob = O:brainmob - O:brainmob = null - brainmob.loc = src - brainmob.container = src - brainmob.stat = 0 - respawnable_list -= brainmob - dead_mob_list -= brainmob//Update dem lists - living_mob_list += brainmob - - user.drop_item() - if(istype(O,/obj/item/organ/internal/brain/xeno)) - name = "Man-Machine Interface: Alien - [brainmob.real_name]" - icon = 'icons/mob/alien.dmi' - icon_state = "AlienMMI" - alien = 1 - else - name = "Man-Machine Interface: [brainmob.real_name]" - icon_state = "mmi_full" - alien = 0 - qdel(O) - - - - feedback_inc("cyborg_mmis_filled",1) - + if(held_brain) + user << "Somehow, this MMI still has a brain in it. Report this to the bug tracker." + log_to_dd("[user] tried to stick a [O] into [src] in [get_area(src)], but the held brain variable wasn't cleared") return - - if(brainmob) - O.attack(brainmob, user)//Oh noooeeeee - // Brainmobs can take damage, but they can't actually die. Maybe should fix. + if(B.status & ORGAN_DEAD) // As it stood, a brain would never become unviable for MMI usage. Perhaps we should keep it that way? + user << "This [B] is dead" return - ..() + for(var/mob/V in viewers(src, null)) + V.show_message("[user] sticks \a [O] into \the [src].") + brainmob = B.brainmob + B.brainmob = null + brainmob.loc = src + brainmob.container = src + brainmob.stat = CONSCIOUS + respawnable_list -= brainmob + dead_mob_list -= brainmob//Update dem lists + living_mob_list += brainmob - - - attack_self(mob/user as mob) - if(!brainmob) - user << "\red You upend the MMI, but there's nothing in it." + user.drop_item() + B.forceMove(src) + held_brain = B + if(istype(O,/obj/item/organ/brain/xeno)) // I'm not sure how well this will work now, since I don't think you can actually get xeno brains + name = "Man-Machine Interface: Alien - [brainmob.real_name]" + icon = 'icons/mob/alien.dmi' + icon_state = "AlienMMI" + alien = 1 else - user << "You unlock and upend the MMI, spilling the brain onto the floor." - if(alien) - var/obj/item/organ/internal/brain/xeno/brain = new(user.loc) - dropbrain(brain,get_turf(user)) - else - var/obj/item/organ/internal/brain/brain = new(user.loc) - dropbrain(brain,get_turf(user)) - icon = 'icons/obj/assemblies.dmi' - icon_state = "mmi_empty" - name = "Man-Machine Interface" - - proc - transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people. - brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - brainmob.container = src - name = "Man-Machine Interface: [brainmob.real_name]" icon_state = "mmi_full" - return + alien = 0 + feedback_inc("cyborg_mmis_filled",1) + + return + + if(brainmob) + O.attack(brainmob, user)//Oh noooeeeee + // Brainmobs can take damage, but they can't actually die. Maybe should fix. + return + ..() + + + +/obj/item/device/mmi/attack_self(mob/user as mob) + if(!brainmob) + user << "You upend the MMI, but there's nothing in it." + else + user << "You unlock and upend the MMI, spilling the brain onto the floor." + dropbrain(get_turf(user)) + icon = 'icons/obj/assemblies.dmi' + icon_state = "mmi_empty" + name = "Man-Machine Interface" + +/obj/item/device/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people. + brainmob = new(src) + brainmob.name = H.real_name + brainmob.real_name = H.real_name + brainmob.dna = H.dna.Clone() + brainmob.container = src + + if(!istype(H.species) || isnull(H.species.return_organ("brain"))) // Diona/buggy people + held_brain = new(src) + else // We have a species, and it has a brain + var/brain_path = H.species.return_organ("brain") + if(!ispath(brain_path, /obj/item/organ/brain)) + brain_path = /obj/item/organ/brain + held_brain = new brain_path(src) // Slime people will keep their slimy brains this way + held_brain.dna = brainmob.dna.Clone() + held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]" + + name = "Man-Machine Interface: [brainmob.real_name]" + icon_state = "mmi_full" + return + //I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the //problem i was having with alien/nonalien brain drops. - dropbrain(var/obj/item/organ/internal/brain/brain, var/turf/dropspot) - brainmob.container = null//Reset brainmob mmi var. - brainmob.loc = brain//Throw mob into brain. - respawnable_list += brainmob - living_mob_list -= brainmob//Get outta here - brain.brainmob = brainmob//Set the brain to use the brainmob - brain.brainmob.cancel_camera() - brainmob = null//Set mmi brainmob var to null +/obj/item/device/mmi/proc/dropbrain(var/turf/dropspot) + if(isnull(held_brain)) + log_to_dd("[src] at [loc] attempted to drop brain without a contained brain in [get_area(src)].") + brainmob << "Your MMI did not contain a brain! We'll make a new one for you, but you'd best report this to the bugtracker!" + held_brain = new(dropspot) // Let's not ruin someone's round because of something dumb -- Crazylemon + held_brain.dna = brainmob.dna.Clone() + held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]" + + brainmob.container = null//Reset brainmob mmi var. + brainmob.loc = held_brain//Throw mob into brain. + respawnable_list += brainmob + living_mob_list -= brainmob//Get outta here + held_brain.brainmob = brainmob//Set the brain to use the brainmob + held_brain.brainmob.cancel_camera() + brainmob = null//Set mmi brainmob var to null + held_brain.forceMove(dropspot) + held_brain = null /obj/item/device/mmi/radio_enabled @@ -106,25 +127,23 @@ var/obj/item/device/radio/radio = null//Let's give it a radio. - New() - ..() - radio = new(src)//Spawns a radio inside the MMI. - radio.broadcasting = 1//So it's broadcasting from the start. +/obj/item/device/mmi/radio_enabled/New() + ..() + radio = new(src)//Spawns a radio inside the MMI. + radio.broadcasting = 1//So it's broadcasting from the start. - verb//Allows the brain to toggle the radio functions. +/obj/item/device/mmi/radio_enabled/verb/Toggle_Listening() + set name = "Toggle Listening" + set desc = "Toggle listening channel on or off." + set category = "MMI" + set src = usr.loc + set popup_menu = 0 - Toggle_Listening() - set name = "Toggle Listening" - set desc = "Toggle listening channel on or off." - set category = "MMI" - set src = usr.loc - set popup_menu = 0 + if(brainmob.stat) + brainmob << "Can't do that while incapacitated or dead." - if(brainmob.stat) - brainmob << "Can't do that while incapacitated or dead." - - radio.listening = radio.listening==1 ? 0 : 1 - brainmob << "\blue Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast." + radio.listening = radio.listening==1 ? 0 : 1 + brainmob << "Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast." /obj/item/device/mmi/emp_act(severity) if(!brainmob) @@ -153,6 +172,9 @@ if(brainmob) qdel(brainmob) brainmob = null + if(held_brain) + qdel(held_brain) + held_brain = null return ..() /obj/item/device/mmi/syndie diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index bb7d27b0aaf..5a0132f6bd8 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/brain +/obj/item/organ/brain name = "brain" health = 400 //They need to live awhile longer than other organs. max_damage = 200 @@ -13,32 +13,39 @@ var/mob/living/carbon/brain/brainmob = null organ_tag = "brain" parent_organ = "head" - slot = "brain" vital = 1 -/obj/item/organ/internal/brain/surgeryize() +/obj/item/organ/brain/attack_self(mob/user as mob) + return //let's not have players taken out of the round as easily as a click, once you have their brain. + +/obj/item/organ/brain/surgeryize() if(!owner) return owner.ear_damage = 0 //Yeah, didn't you...hear? The ears are totally inside the brain. owner.ear_deaf = 0 -/obj/item/organ/internal/brain/xeno +/obj/item/organ/brain/xeno name = "thinkpan" desc = "It looks kind of like an enormous wad of purple bubblegum." - icon_state = "brain-x-d" + icon = 'icons/mob/alien.dmi' + icon_state = "chitin" -/obj/item/organ/internal/brain/New() +/obj/item/organ/brain/New() ..() spawn(5) if(brainmob && brainmob.client) brainmob.client.screen.len = null //clear the hud -/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H) - name = "\the [H]'s [initial(src.name)]" +/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H) brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() + if(isnull(dna)) // someone didn't set this right... + log_to_dd("[src] at [loc] did not contain a dna datum at time of removed.") + dna = H.dna.Clone() + name = "\the [dna.real_name]'s [initial(src.name)]" + brainmob.dna = dna.Clone() // Silly baycode, what you do +// brainmob.dna = H.dna.Clone() Putting in and taking out a brain doesn't make it a carbon copy of the original brain of the body you put it in + brainmob.name = dna.real_name + brainmob.real_name = dna.real_name brainmob.timeofhostdeath = H.timeofdeath if(H.mind) H.mind.transfer_to(brainmob) @@ -46,61 +53,63 @@ brainmob << "You feel slightly disoriented. That's normal when you're just a [initial(src.name)]." callHook("debrain", list(brainmob)) -/obj/item/organ/internal/brain/examine(mob/user) // -- TLE +/obj/item/organ/brain/examine(mob/user) // -- TLE ..(user) if(brainmob && brainmob.client)//if thar be a brain inside... the brain. user << "You can feel the small spark of life still left in this one." else user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.." -/obj/item/organ/internal/brain/Remove(var/mob/living/user) +/obj/item/organ/brain/removed(var/mob/living/user) if(!owner) return ..() // Probably a redundant removal; just bail - name = "[owner.real_name]'s brain" - var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() + var/obj/item/organ/brain/B = src + if(istype(B) && istype(owner) && is_primary_organ()) + var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() - if(borer) - borer.detatch() //Should remove borer if the brain is removed - RR + if(borer) + borer.detatch() //Should remove borer if the brain is removed - RR - owner.brain_op_stage = 4.0 - - var/obj/item/organ/internal/brain/B = src - if(istype(B) && istype(owner)) + owner.brain_op_stage = 4.0 B.transfer_identity(owner) ..() -/obj/item/organ/internal/brain/Insert(var/mob/living/target) +/obj/item/organ/brain/replaced(var/mob/living/target) - if(target.key) - target.ghostize() - var/mob/living/carbon/C = target - if(istype(C)) - C.brain_op_stage = 1.0 - if(brainmob) - if(brainmob.mind) - brainmob.mind.transfer_to(target) - else - target.key = brainmob.key + var/brain_already_exists = 0 + if(istype(target,/mob/living/carbon/human)) // No more IPC multibrain shenanigans + var/mob/living/carbon/human/H = target + if(organ_tag in H.internal_organs_by_name) + brain_already_exists = 1 + + if(!brain_already_exists) + if(target.key) + target.ghostize() + var/mob/living/carbon/C = target + if(istype(C)) + C.brain_op_stage = 1.0 + if(brainmob) + if(brainmob.mind) + brainmob.mind.transfer_to(target) + else + target.key = brainmob.key ..() -/obj/item/organ/internal/brain/prepare_eat() - return // Too important to eat. - -/obj/item/organ/internal/brain/slime +/obj/item/organ/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." icon = 'icons/mob/slimes.dmi' icon_state = "green slime extract" -/obj/item/organ/internal/brain/golem +/obj/item/organ/brain/golem name = "chem" desc = "A tightly furled roll of paper, covered with indecipherable runes." icon = 'icons/obj/wizard.dmi' icon_state = "scroll" -/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs. +/obj/item/organ/brain/Destroy() //copypasted from MMIs. if(brainmob) qdel(brainmob) brainmob = null diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 85de7330052..82f35730bf8 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -24,10 +24,15 @@ var/list/organ_cache = list() var/datum/dna/dna var/datum/species/species + // Stuff for tracking if this is on a tile with an open freezer or not + var/last_freezer_update_time = 0 + var/freezer_update_period = 100 + var/is_in_freezer = 0 + /obj/item/organ/Destroy() if(!owner) return ..() -/* + if(istype(owner, /mob/living/carbon)) if((owner.internal_organs) && (src in owner.internal_organs)) owner.internal_organs -= src @@ -38,12 +43,17 @@ var/list/organ_cache = list() owner.organs -= src if((owner.organs_by_name) && (src in owner.organs_by_name)) owner.organs_by_name -= src -*/ if(src in owner.contents) owner.contents -= src return ..() +/obj/item/organ/attack_self(mob/user as mob) + + // Convert it to an edible form, yum yum. + if(!robotic && user.a_intent == I_HARM) + bitten(user) + return /obj/item/organ/proc/update_health() return @@ -101,8 +111,7 @@ var/list/organ_cache = list() if(status & ORGAN_DEAD) return - // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? - if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) + if(is_preserved()) return //Process infections @@ -116,8 +125,11 @@ var/list/organ_cache = list() if(B && prob(40)) reagents.remove_reagent("blood",0.1) blood_splatter(src,B,1) - - germ_level += rand(2,6) + // Maybe scale it down a bit, have it REALLY kick in once past the basic infection threshold + // Another mercy for surgeons preparing transplant organs + germ_level++ + if(germ_level >= INFECTION_LEVEL_ONE) + germ_level += rand(2,6) if(germ_level >= INFECTION_LEVEL_TWO) germ_level += rand(2,6) if(germ_level >= INFECTION_LEVEL_THREE) @@ -135,6 +147,30 @@ var/list/organ_cache = list() if(damage >= max_damage) die() +/obj/item/organ/proc/is_preserved() + if(istype(loc,/obj/item/device/mmi)) + germ_level = max(0, germ_level - 1) // So a brain can slowly recover from being left out of an MMI + return 1 + if(is_found_within(/obj/item/bodybag/cryobag)) + return 1 + if(is_found_within(/obj/structure/closet/crate/freezer)) + return 1 + if(istype(loc,/turf)) + if(world.time - last_freezer_update_time > freezer_update_period) + // I don't want to loop through everything in the tile constantly, especially since it'll be a pile of organs + // if the virologist releases gibbingtons again or something + // There's probably a much less silly way of doing this, but BYOND native algorithms are stupidly naive + is_in_freezer = 0 + for(var/obj/structure/closet/crate/freezer/F in loc.contents) + if(F.opened) + is_in_freezer = 1 // on the same tile, close enough, should keep organs much fresher on avg + break + last_freezer_update_time = world.time + return is_in_freezer // I'd like static varibles, please + + // You can do your cool location temperature organ preserving effects here! + return 0 + /obj/item/organ/examine(mob/user) ..(user) if(status & ORGAN_DEAD) @@ -170,6 +206,7 @@ var/list/organ_cache = list() /obj/item/organ/proc/rejuvenate() damage = 0 + germ_level = 0 /obj/item/organ/proc/is_damaged() return damage > 0 @@ -184,15 +221,16 @@ var/list/organ_cache = list() /obj/item/organ/proc/handle_antibiotics() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if (!germ_level || antibiotics < 5) + if (!germ_level || antibiotics <= 0.4) return if (germ_level < INFECTION_LEVEL_ONE) germ_level = 0 //cure instantly else if (germ_level < INFECTION_LEVEL_TWO) - germ_level -= 6 //at germ_level == 500, this should cure the infection in a minute + germ_level -= 24 //at germ_level == 500, this should cure the infection in 15 seconds else - germ_level -= 2 //at germ_level == 1000, this will cure the infection in 5 minutes + germ_level -= 8 // at germ_level == 1000, this will cure the infection in 1 minute, 15 seconds + // Let's not drag this on, medbay has only so much antibiotics //Adds autopsy data for used_weapon. /obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage) @@ -251,10 +289,16 @@ var/list/organ_cache = list() take_damage(0,3) /obj/item/organ/proc/removed(var/mob/living/user) - if(!istype(owner)) return + if(is_primary_organ()) + owner.internal_organs_by_name[organ_tag] = null + owner.internal_organs_by_name -= organ_tag + owner.internal_organs_by_name -= null // uh what does this line even do this seems silly + + owner.internal_organs -= src + var/obj/item/organ/external/affected = owner.get_organ(parent_organ) if(affected) affected.internal_organs -= src @@ -265,7 +309,7 @@ var/list/organ_cache = list() if(!organ_blood || !organ_blood.data["blood_DNA"]) owner.vessel.trans_to(src, 5, 1, 1) - if(owner && vital) + if(owner && vital && is_primary_organ()) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead if(user) user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [key_name(owner)] (INTENT: [uppertext(user.a_intent)])" owner.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [key_name(user)] (INTENT: [uppertext(user.a_intent)])" @@ -279,12 +323,54 @@ var/list/organ_cache = list() owner = target processing_objects -= src - //target.internal_organs |= src + target.internal_organs |= src affected.internal_organs |= src - //target.internal_organs_by_name[organ_tag] = src + if (!(organ_tag in target.internal_organs_by_name)) + target.internal_organs_by_name[organ_tag] = src // In case multiple of the same type are inserted, only the first one is the primary organ src.loc = target if(robotic) status |= ORGAN_ROBOT +/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) + + // Apply our eye colour to the target. + if(istype(target) && eye_colour) + target.r_eyes = eye_colour[1] + target.g_eyes = eye_colour[2] + target.b_eyes = eye_colour[3] + target.update_eyes() + ..() + +/obj/item/organ/proc/bitten(mob/user) + + if(robotic) + return + + user << "\blue You take a bite out of \the [src]." + + user.unEquip(src) + var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src)) + O.name = name + O.icon_state = dead_icon ? dead_icon : icon_state + + if(fingerprints) O.fingerprints = fingerprints.Copy() + if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy() + if(fingerprintslast) O.fingerprintslast = fingerprintslast + + user.put_in_active_hand(O) + qdel(src) + /obj/item/organ/proc/surgeryize() - return \ No newline at end of file + return + +/* +Returns 1 if this is the organ that is handling all the functionalities of that particular organ slot +Returns 0 if it isn't +I use this so that this can be made better once the organ overhaul rolls out -- Crazylemon +*/ +/obj/item/organ/proc/is_primary_organ(var/mob/living/carbon/human/O = null) + if (isnull(O)) + O = owner + if (!istype(owner)) // You're not the primary organ of ANYTHING, bucko + return 0 + return src == O.internal_organs_by_name[organ_tag] diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index dc28e8e22d0..46d7f01b0d9 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -3,148 +3,26 @@ /**************************************************** INTERNAL ORGANS DEFINES ****************************************************/ -/obj/item/organ/internal - origin_tech = "biotech=2" - force = 1 - w_class = 2 - throwforce = 0 - organ_tag = "guts" - parent_organ = "chest" //aka the zone - var/slot - vital = 0 - var/organ_action_name = null -/obj/item/organ/internal/proc/Insert(mob/living/carbon/M, special = 0)//insert the thing into the slot - if(!iscarbon(M) || owner == M) - return - - var/obj/item/organ/internal/replaced = M.get_organ_slot(slot) - if(replaced) - replaced.Remove(M, special = 1) - - owner = M - M.internal_organs |= src - //M.internal_organs_by_name[organ_tag] = src - loc = null - if(organ_action_name) - action_button_name = organ_action_name - -/obj/item/organ/internal/proc/Remove(mob/living/carbon/M, special = 0) - owner = null - if(M) - // M.internal_organs_by_name[organ_tag] = null - // M.internal_organs_by_name -= organ_tag - // M.internal_organs_by_name -= null - M.internal_organs -= src - - if(vital && !special) - M.death() - - - if(organ_action_name) - action_button_name = null - -/obj/item/organ/internal/proc/on_find(mob/living/finder) - return - -/obj/item/organ/internal/proc/on_life() - return - - -/obj/item/organ/internal/proc/prepare_eat() - var/obj/item/weapon/reagent_containers/food/snacks/organ/S = new - S.name = name - S.desc = desc - S.icon = icon - S.icon_state = icon_state - S.origin_tech = origin_tech - S.w_class = w_class - - return S - -/obj/item/weapon/reagent_containers/food/snacks/organ - name = "appendix" - icon_state = "appendix" - icon = 'icons/obj/surgery.dmi' - -/obj/item/weapon/reagent_containers/food/snacks/organ/New() - - ..() - - reagents.add_reagent("nutriment",5) - - -/obj/item/organ/internal/Destroy() - if(owner) - Remove(owner, 1) - return - -/obj/item/organ/internal/attack(mob/living/carbon/M, mob/user) - if(robotic) - return - - if(M == user && ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/weapon/reagent_containers/food/snacks/S = prepare_eat() - if(S) - H.unEquip() - H.put_in_active_hand(S) - if(fingerprints) S.fingerprints = fingerprints.Copy() - if(fingerprintshidden) S.fingerprintshidden = fingerprintshidden.Copy() - if(fingerprintslast) S.fingerprintslast = fingerprintslast - S.attack(H, H) - qdel(src) - else - ..() - - -///THE ORGANS // Brain is defined in brain_item.dm. -/obj/item/organ/internal/heart +/obj/item/organ/heart name = "heart" icon_state = "heart-on" organ_tag = "heart" parent_organ = "chest" - slot = "heart" - origin_tech = "biotech=3" + dead_icon = "heart-off" vital = 1 - var/beating -/obj/item/organ/internal/heart/update_icon() - if(beating) - icon_state = "heart-on" - else - icon_state = "heart-off" - -/obj/item/organ/internal/heart/Insert(mob/living/carbon/M, special = 0) - ..() - beating = 1 - update_icon() - -/obj/item/organ/internal/heart/Remove(mob/living/carbon/M, special = 0) - ..() - spawn(120) - beating = 0 - update_icon() - -/obj/item/organ/internal/heart/prepare_eat() - var/obj/S = ..() - S.icon_state = "heart-off" - return S - -/obj/item/organ/internal/lungs +/obj/item/organ/lungs name = "lungs" icon_state = "lungs" gender = PLURAL organ_tag = "lungs" parent_organ = "chest" - slot = "lungs" - origin_tech = "biotech=2" -/obj/item/organ/internal/lungs/process()///Fethas note, Should this be organ on life? +/obj/item/organ/lungs/process() ..() -//to_do per fethas: Could we handle some of the species breathing in here? if(!owner) return @@ -161,17 +39,14 @@ spawn owner.custom_emote(1, "gasps for air!") owner.losebreath += 5 -/obj/item/organ/internal/kidneys +/obj/item/organ/kidneys name = "kidneys" icon_state = "kidneys" gender = PLURAL organ_tag = "kidneys" parent_organ = "groin" - slot = "kidneys" - origin_tech = "biotech=2" - -/obj/item/organ/internal/kidneys/process() +/obj/item/organ/kidneys/process() ..() @@ -189,39 +64,24 @@ owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) -/obj/item/organ/internal/eyes +/obj/item/organ/eyes name = "eyeballs" icon_state = "eyes" gender = PLURAL organ_tag = "eyes" parent_organ = "head" - slot = "eyes" - origin_tech = "biotech=2" var/list/eye_colour = list(0,0,0) -/obj/item/organ/internal/eyes/proc/update_colour() +/obj/item/organ/eyes/proc/update_colour() if(!owner) return - if(istype(owner,/mob/living/carbon/human)) - var/mob/living/carbon/human/eyes = owner - eye_colour = list( - eyes.r_eyes ? owner.r_eyes : 0, - eyes.g_eyes ? owner.g_eyes : 0, - eyes.b_eyes ? owner.b_eyes : 0 - ) + eye_colour = list( + owner.r_eyes ? owner.r_eyes : 0, + owner.g_eyes ? owner.g_eyes : 0, + owner.b_eyes ? owner.b_eyes : 0 + ) -/obj/item/organ/internal/eyes/Insert(mob/living/carbon/M, special = 0) - ..() - // Apply our eye colour to the target. - if(istype(M,/mob/living/carbon/human) && eye_colour) - var/mob/living/carbon/human/eyes = M - eyes.r_eyes = eye_colour[1] - eyes.g_eyes = eye_colour[2] - eyes.b_eyes = eye_colour[3] - eyes.update_eyes() - - -/obj/item/organ/internal/eyes/surgeryize() +/obj/item/organ/eyes/surgeryize() if(!owner) return owner.disabilities &= ~NEARSIGHTED @@ -229,15 +89,13 @@ owner.eye_blurry = 0 owner.eye_blind = 0 -/obj/item/organ/internal/liver +/obj/item/organ/liver name = "liver" icon_state = "liver" organ_tag = "liver" parent_organ = "groin" - slot = "liver" - origin_tech = "biotech=1" -/obj/item/organ/internal/liver/process() +/obj/item/organ/liver/process() ..() @@ -290,13 +148,12 @@ if(owner.reagents.has_reagent(toxin)) owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) -/obj/item/organ/internal/appendix +/obj/item/organ/appendix name = "appendix" icon_state = "appendix" organ_tag = "appendix" parent_organ = "groin" - slot = "appendix" - origin_tech = "biotech=1" + /* /obj/item/organ/appendix/removed() @@ -311,36 +168,4 @@ icon_state = "appendixinflamed" name = "inflamed appendix" ..() -*/ - -//shadowling brain tumor -/obj/item/organ/internal/shadowtumor - name = "black tumor" - desc = "A tiny black mass with red tendrils trailing from it. It seems to shrivel in the light." - icon_state = "blacktumor" - origin_tech = "biotech=4" - w_class = 1 - organ_tag = "blacktumor" - parent_organ = "head" - slot = "brain_tumor" - health = 3 - -/obj/item/organ/internal/shadowtumor/New() - ..() - processing_objects.Add(src) - -/obj/item/organ/internal/shadowtumor/Destroy() - processing_objects.Remove(src) - ..() - -/obj/item/organ/internal/shadowtumor/process() - if(isturf(loc)) - var/turf/T = loc - var/light_count = T.get_lumcount() - if(light_count > 4 && health > 0) //Die in the light - health-- - else if(light_count < 2 && health < 3) //Heal in the dark - health++ - if(health <= 0) - visible_message("[src] collapses in on itself!") - qdel(src) \ No newline at end of file +*/ \ No newline at end of file diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 62fa8fca992..87f0e3318cd 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -156,6 +156,10 @@ user.visible_message("\blue [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ "\blue You finish patching damage to [target]'s [affected.name] with \the [tool].") affected.heal_damage(rand(30,50),0,1,1) + if(affected.disfigured) + affected.disfigured = 0 + affected.update_icon() + target.regenerate_icons() fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -220,7 +224,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!affected) return var/is_organ_damaged = 0 - for(var/obj/item/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I.damage > 0 && I.robotic >= 2) is_organ_damaged = 1 break @@ -232,7 +236,7 @@ return var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/obj/item/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ @@ -247,7 +251,7 @@ return var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/obj/item/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) @@ -267,7 +271,7 @@ target.adjustToxLoss(5) affected.createwound(CUT, 5) - for(var/obj/item/organ/internal/I in affected.internal_organs) + for(var/obj/item/organ/I in affected.internal_organs) if(I) I.take_damage(rand(3,5),0) @@ -289,18 +293,20 @@ return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/attached_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] - if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - attached_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(I && istype(I) && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + attached_organs[I.organ_tag] = I var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs if(!organ_to_remove) return 0 target.op_stage.current_organ = organ_to_remove + target.op_stage.organ_ref = attached_organs[organ_to_remove] return ..() && organ_to_remove @@ -313,7 +319,7 @@ user.visible_message("\blue [user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].") - var/obj/item/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status |= ORGAN_CUT_AWAY @@ -338,18 +344,20 @@ return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/removable_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] - if(I && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(I && istype(I) && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) + removable_organs[I.organ_tag] = I var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs if(!organ_to_replace) return 0 target.op_stage.current_organ = organ_to_replace + target.op_stage.organ_ref = removable_organs[organ_to_replace] return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -361,7 +369,7 @@ user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - var/obj/item/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY @@ -424,7 +432,7 @@ "\blue You have installed \the [tool] into [target]'s [affected.name].") var/obj/item/device/mmi/M = tool - var/obj/item/organ/internal/mmi_holder/holder = new(target, 1) + var/obj/item/organ/mmi_holder/holder = new(target, 1) if (istype(M, /obj/item/device/mmi/posibrain)) holder.robotize() diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 4a54071d83c..e772ea8d048 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ