From 691f6fb66dbd313933fad6b4cd8cb950e9bb42d5 Mon Sep 17 00:00:00 2001 From: c0 Date: Thu, 6 Aug 2015 09:56:54 +0300 Subject: [PATCH] Surgery & Organs Rework: Phase 2 --- code/datums/martial.dm | 2 +- code/datums/spells/inflict_handler.dm | 2 +- code/datums/spells/summonitem.dm | 62 +++++----- code/game/gamemodes/abduction/gland.dm | 3 +- .../gamemodes/changeling/powers/headcrab.dm | 2 +- code/game/gamemodes/cult/runes.dm | 4 +- .../gamemodes/shadowling/shadowling_items.dm | 15 +++ code/game/gamemodes/wizard/godhand.dm | 2 +- code/game/machinery/cloning.dm | 2 +- code/game/machinery/computer/cloning.dm | 2 +- code/game/objects/items/body_egg.dm | 4 + code/game/objects/items/devices/scanners.dm | 2 +- .../recipes/tablecraft/recipes_burger.dm | 2 +- .../recipes/tablecraft/recipes_cake.dm | 2 +- code/modules/mining/abandoned_crates.dm | 4 +- code/modules/mob/living/carbon/alien/alien.dm | 2 +- .../carbon/alien/humanoid/caste/drone.dm | 2 +- .../carbon/alien/special/alien_embryo.dm | 38 ++++-- code/modules/mob/living/carbon/brain/MMI.dm | 10 +- .../mob/living/carbon/brain/brain_item.dm | 97 ++++++++------- code/modules/mob/living/carbon/brain/death.dm | 4 +- .../mob/living/carbon/human/examine.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/species.dm | 2 +- code/modules/mob/living/carbon/life.dm | 2 +- .../mob/living/carbon/monkey/monkey.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- code/modules/surgery/appendectomy.dm | 32 ----- code/modules/surgery/brain_removal.dm | 43 ------- code/modules/surgery/core_removal.dm | 5 +- code/modules/surgery/cybernetic_implants.dm | 80 ------------- code/modules/surgery/dethrall.dm | 9 +- code/modules/surgery/eye_surgery.dm | 2 +- code/modules/surgery/generic_steps.dm | 10 +- code/modules/surgery/helpers.dm | 2 +- code/modules/surgery/limb augmentation.dm | 9 +- code/modules/surgery/organ_manipulation.dm | 111 ++++++++++++++++++ code/modules/surgery/organs/helpers.dm | 10 +- code/modules/surgery/organs/organ_internal.dm | 66 +++++++++-- code/modules/surgery/surgery.dm | 1 - code/modules/surgery/surgery_step.dm | 6 +- code/modules/surgery/xenomorph_removal.dm | 50 -------- icons/obj/surgery.dmi | Bin 12861 -> 13088 bytes tgstation.dme | 6 +- 44 files changed, 363 insertions(+), 356 deletions(-) delete mode 100644 code/modules/surgery/appendectomy.dm delete mode 100644 code/modules/surgery/brain_removal.dm delete mode 100644 code/modules/surgery/cybernetic_implants.dm create mode 100644 code/modules/surgery/organ_manipulation.dm delete mode 100644 code/modules/surgery/xenomorph_removal.dm diff --git a/code/datums/martial.dm b/code/datums/martial.dm index f54df12a0c4..96d8726d596 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -243,7 +243,7 @@ A.say("PLASMA FIST!") D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \ "[A] has hit [D] with THE PLASMA FIST TECHNIQUE!") - var/obj/item/organ/brain/B = D.getorgan(/obj/item/organ/brain) + var/obj/item/organ/internal/brain/B = D.getorgan(/obj/item/organ/internal/brain) if(B) B.loc = get_turf(D) B.transfer_identity(D) diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index c4ba6c45524..e82d3ce2003 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -29,7 +29,7 @@ if("gib_brain") if(ishuman(target) || ismonkey(target)) var/mob/living/carbon/C_target = target - var/obj/item/organ/brain/B = C_target.getorgan(/obj/item/organ/brain) + var/obj/item/organ/internal/brain/B = C_target.getorgan(/obj/item/organ/internal/brain) if(B) B.loc = get_turf(C_target) B.transfer_identity(C_target) diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index 7b29e448844..2f8116ffe6b 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -44,7 +44,7 @@ name = "Instant Summons" marked_item = null - else if(marked_item && !marked_item.loc) //the item was destroyed at some point + else if(marked_item && marked_item.gc_destroyed) //the item was destroyed at some point message = "You sense your marked item has been destroyed!" name = "Instant Summons" marked_item = null @@ -53,44 +53,46 @@ var/obj/item_to_retrive = marked_item var/infinite_recursion = 0 //I don't want to know how someone could put something inside itself but these are wizards so let's be safe - while(!isturf(item_to_retrive.loc) && infinite_recursion < 10) //if it's in something you get the whole thing. - if(ismob(item_to_retrive.loc)) //If its on someone, properly drop it - var/mob/M = item_to_retrive.loc + if(!item_to_retrive.loc) + if(isorgan(item_to_retrive)) // Organs are usually stored in nullspace + var/obj/item/organ/internal/organ = item_to_retrive + if(organ.owner) + // If this code ever runs I will be happy + add_logs(user, organ.owner, "magically removed [organ.name] from", addition="INTENT: [uppertext(user.a_intent)]") + organ.Remove(organ.owner) + else + while(!isturf(item_to_retrive.loc) && infinite_recursion < 10) //if it's in something you get the whole thing. + if(ismob(item_to_retrive.loc)) //If its on someone, properly drop it + var/mob/M = item_to_retrive.loc - if(issilicon(M)) //Items in silicons warp the whole silicon - M.loc.visible_message("[M] suddenly disappears!") - M.loc = user.loc - M.loc.visible_message("[M] suddenly appears!") - item_to_retrive = null - break + if(issilicon(M)) //Items in silicons warp the whole silicon + M.loc.visible_message("[M] suddenly disappears!") + M.loc = user.loc + M.loc.visible_message("[M] suddenly appears!") + item_to_retrive = null + break + M.unEquip(item_to_retrive) - M.unEquip(item_to_retrive) + if(iscarbon(M)) //Edge case housekeeping + var/mob/living/carbon/C = M + if(C.stomach_contents && item_to_retrive in C.stomach_contents) + C.stomach_contents -= item_to_retrive - if(iscarbon(M)) //Edge case housekeeping - var/mob/living/carbon/C = M - if(C.internal_organs && item_to_retrive in C.internal_organs) //KALIMA! - C.internal_organs -= item_to_retrive - if(istype(marked_item,/obj/item/organ/brain)) //If this code ever runs I will be happy - var/obj/item/organ/brain/B - B.transfer_identity(C) - add_logs(user, C, "magically debrained", addition="INTENT: [uppertext(user.a_intent)]") - if(C.stomach_contents && item_to_retrive in C.stomach_contents) - C.stomach_contents -= item_to_retrive + else + if(istype(item_to_retrive.loc,/obj/machinery/portable_atmospherics/)) //Edge cases for moved machinery + var/obj/machinery/portable_atmospherics/P = item_to_retrive.loc + P.disconnect() + P.update_icon() - else - if(istype(item_to_retrive.loc,/obj/machinery/portable_atmospherics/)) //Edge cases for moved machinery - var/obj/machinery/portable_atmospherics/P = item_to_retrive.loc - P.disconnect() - P.update_icon() + item_to_retrive = item_to_retrive.loc - item_to_retrive = item_to_retrive.loc - - infinite_recursion += 1 + infinite_recursion += 1 if(!item_to_retrive) return - item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly disappears!") + if(item_to_retrive.loc) + item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly disappears!") if(user.hand) //left active hand diff --git a/code/game/gamemodes/abduction/gland.dm b/code/game/gamemodes/abduction/gland.dm index cf3b766282e..fd2ecdcce4c 100644 --- a/code/game/gamemodes/abduction/gland.dm +++ b/code/game/gamemodes/abduction/gland.dm @@ -175,8 +175,7 @@ /obj/item/organ/internal/gland/spiderman/activate() owner << "You feel something crawling in your skin." - if(uses == initial(uses)) - owner.faction += "spiders" + owner.faction |= "spiders" new /obj/effect/spider/spiderling(owner.loc) /obj/item/organ/internal/gland/egg diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm index 0f4b1f855ca..4440e9b63d9 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -7,7 +7,7 @@ /obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user) var/datum/mind/M = user.mind - var/list/organs = user.getorganszone("head") + user.getorganszone("eyes") + var/list/organs = user.getorganszone("head", 1) for(var/obj/item/organ/internal/I in organs) I.Remove(user, 1) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 6d69be02b67..ab505d83329 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -529,8 +529,8 @@ var/list/sacrificed = list() if(!(iscultist(V))) victims += V//Checks for cult status and mob type for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/organ/brain)) - var/obj/item/organ/brain/B = I + if(istype(I,/obj/item/organ/internal/brain)) + var/obj/item/organ/internal/brain/B = I victims += B.brainmob else if(istype(I,/obj/item/device/mmi)) var/obj/item/device/mmi/B = I diff --git a/code/game/gamemodes/shadowling/shadowling_items.dm b/code/game/gamemodes/shadowling/shadowling_items.dm index 5d5de93e57b..83ef7109156 100644 --- a/code/game/gamemodes/shadowling/shadowling_items.dm +++ b/code/game/gamemodes/shadowling/shadowling_items.dm @@ -100,3 +100,18 @@ td << "You enter the rift. Deafening chimes jingle in your ears. You are swallowed in darkness." playsound(loc, 'sound/effects/EMPulse.ogg', 25, 1) qdel(td) + + +/obj/item/organ/internal/shadowtumor + name = "black tumor" + icon_state = "blacktumor" + origin_tech = "biotech=4" + w_class = 1 + zone = "head" + slot = "brain_tumor" + +/obj/item/organ/internal/shadowtumor/on_find(mob/living/finder) + finder << "You locate a small, pulsing black tumor in [owner]'s head!" + owner << "A small part of your head pulses with agony as the light impacts it!" + +// TODO: replace dethrall surgery with this + organ manipulation, somehow. \ No newline at end of file diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm index 874ebfa7aaa..f0d57d5784d 100644 --- a/code/game/gamemodes/wizard/godhand.dm +++ b/code/game/gamemodes/wizard/godhand.dm @@ -46,7 +46,7 @@ var/mob/M = target if(ishuman(M) || ismonkey(M)) var/mob/living/carbon/C_target = M - var/obj/item/organ/brain/B = C_target.getorgan(/obj/item/organ/brain) + var/obj/item/organ/internal/brain/B = C_target.getorgan(/obj/item/organ/internal/brain) if(B) B.loc = get_turf(C_target) B.transfer_identity(C_target) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 6c76c19e864..c2613b9a80c 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -70,7 +70,7 @@ if ((M.stat != 2) || (!M.client)) continue //They need a brain! - if (ishuman(M) && !M.getorgan(/obj/item/organ/brain)) + if (ishuman(M) && !M.getorgan(/obj/item/organ/internal/brain)) continue if (M.ckey == find_key) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index a75a603344b..213c8d56a89 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -353,7 +353,7 @@ if (!check_dna_integrity(subject) || !istype(subject)) scantemp = "Unable to locate valid genetic data." return - if (!subject.getorgan(/obj/item/organ/brain)) + if (!subject.getorgan(/obj/item/organ/internal/brain)) scantemp = "No signs of intelligence detected." return if (subject.suiciding == 1) diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index c3a71b8f485..8fad18c31cc 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -6,6 +6,10 @@ zone = "chest" slot = "parasite_egg" +/obj/item/organ/internal/body_egg/on_find(mob/living/finder) + ..() + finder << "You found an unknown alien organism in [owner]'s [zone]!" + /obj/item/organ/internal/body_egg/New(loc) if(iscarbon(loc)) src.Insert(loc) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 16769bb4b99..c4f2a7190e5 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -143,7 +143,7 @@ MASS SPECTROMETER user << "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage." if (M.reagents && M.reagents.get_reagent_amount("epinephrine")) user << "\tBloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals." - if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain)) + if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/internal/brain)) user << "\tSubject brain function is non-existant." else if (M.getBrainLoss() >= 60) user << "\tSevere brain damage detected. Subject likely to have mental retardation." diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm index ef5f43f7495..b59321db533 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm @@ -45,7 +45,7 @@ /datum/table_recipe/brainburger name = "Brain burger" reqs = list( - /obj/item/organ/brain = 1, + /obj/item/organ/internal/brain = 1, /obj/item/weapon/reagent_containers/food/snacks/bun = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/burger/brain diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm index df5f99fb6bb..eb52389a1b8 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm @@ -78,7 +78,7 @@ /datum/table_recipe/braincake name = "Brain cake" reqs = list( - /obj/item/organ/brain = 1, + /obj/item/organ/internal/brain = 1, /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/brain diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 81a3f2a4cf5..06c4f46ae2c 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -110,9 +110,9 @@ if(87) //1% chance new /obj/item/weed_extract(src) if(88) - new /obj/item/organ/brain(src) + new /obj/item/organ/internal/brain(src) if(89) - new /obj/item/organ/brain/alien(src) + new /obj/item/organ/internal/brain/alien(src) if(90) new /obj/item/organ/internal/heart(src) if(91) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index f96c94af11a..529c9c4ad60 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -35,7 +35,7 @@ verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down - internal_organs += new /obj/item/organ/brain/alien + internal_organs += new /obj/item/organ/internal/brain/alien for(var/obj/item/organ/internal/I in internal_organs) I.Insert(src) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index ac8b2f4405d..2e3a40ff237 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -34,7 +34,7 @@ /obj/effect/proc_holder/alien/evolve/fire(mob/living/carbon/alien/user) var/no_queen = 1 for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list) - if(!Q.key || !Q.getorgan(/obj/item/organ/brain)) + if(!Q.key || !Q.getorgan(/obj/item/organ/internal/brain)) continue no_queen = 0 if(no_queen) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index b62a11e5153..6995c025b0e 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -8,27 +8,41 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds icon_state = "larva0_dead" var/stage = 0 +/obj/item/organ/internal/body_egg/alien_embryo/on_find(mob/living/finder) + ..() + if(stage < 4) + finder << "It's small and weak, barely the size of a foetus." + else + finder << "It's grown quite large, and writhes slightly as you look at it." + if(prob(10)) + AttemptGrow(0) + +/obj/item/organ/internal/body_egg/alien_embryo/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("sacid", 10) + return S + /obj/item/organ/internal/body_egg/alien_embryo/on_life() switch(stage) if(2, 3) - if(prob(1)) + if(prob(2)) owner.emote("sneeze") - if(prob(1)) - owner.emote("cough") - if(prob(1)) - owner << "Your throat feels sore." - if(prob(1)) - owner << "Mucous runs down the back of your throat." - if(4) - if(prob(1)) - owner.emote("sneeze") - if(prob(1)) + if(prob(2)) owner.emote("cough") if(prob(2)) + owner << "Your throat feels sore." + if(prob(2)) + owner << "Mucous runs down the back of your throat." + if(4) + if(prob(2)) + owner.emote("sneeze") + if(prob(2)) + owner.emote("cough") + if(prob(4)) owner << "Your muscles ache." if(prob(20)) owner.take_organ_damage(1) - if(prob(2)) + if(prob(4)) owner << "Your stomach hurts." if(prob(20)) owner.adjustToxLoss(1) diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index ec1fd6b67fb..7412dd48ab0 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -18,11 +18,11 @@ var/mob/living/carbon/brain/brainmob = null //The current occupant. var/mob/living/silicon/robot = null //Appears unused. var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm. - var/obj/item/organ/brain/brain = null //The actual brain + var/obj/item/organ/internal/brain/brain = null //The actual brain /obj/item/device/mmi/update_icon() if(brain) - if(istype(brain,/obj/item/organ/brain/alien)) + if(istype(brain,/obj/item/organ/internal/brain/alien)) icon_state = "mmi_alien" braintype = "Xenoborg" //HISS....Beep. else @@ -33,8 +33,8 @@ /obj/item/device/mmi/attackby(obj/item/O, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) - if(istype(O,/obj/item/organ/brain)) //Time to stick a brain in it --NEO - var/obj/item/organ/brain/newbrain = O + if(istype(O,/obj/item/organ/internal/brain)) //Time to stick a brain in it --NEO + var/obj/item/organ/internal/brain/newbrain = O if(brain) user << "There's already a brain in the MMI!" return @@ -110,7 +110,7 @@ brainmob.container = src if(istype(H)) - var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain) + var/obj/item/organ/internal/brain/newbrain = H.getorgan(/obj/item/organ/internal/brain) newbrain.loc = src brain = newbrain diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 5df89ec19ae..21e701b4940 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,20 +1,48 @@ -/obj/item/organ/brain +/obj/item/organ/internal/brain name = "brain" desc = "A piece of juicy meat found in a person's head." - icon = 'icons/obj/surgery.dmi' icon_state = "brain" - force = 1.0 - w_class = 2.0 - throwforce = 0 throw_speed = 3 throw_range = 5 layer = 4.1 + zone = "head" + slot = "brain" + vital = 1 origin_tech = "biotech=4" attack_verb = list("attacked", "slapped", "whacked") var/mob/living/carbon/brain/brainmob = null +/obj/item/organ/internal/brain/Insert(mob/living/carbon/M, special = 0) + ..() + name = "brain" + if(brainmob) + if(M.key) + M.ghostize() -/obj/item/organ/brain/New() + if(brainmob.mind) + brainmob.mind.transfer_to(M) + else + M.key = brainmob.key + + qdel(brainmob) + + //Update the body's icon so it doesnt appear debrained anymore + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.update_hair(0) + +/obj/item/organ/internal/brain/Remove(mob/living/carbon/M, special = 0) + ..() + if(!special) + transfer_identity(M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.update_hair(0) + +/obj/item/organ/internal/brain/prepare_eat() + return // Too important to eat. + +/obj/item/organ/internal/brain/New() ..() //Shifting the brain "mob" over to the brain object so it's easier to keep track of. --NEO spawn(5) @@ -22,19 +50,21 @@ brainmob.client.screen.len = null //clear the hud -/obj/item/organ/brain/proc/transfer_identity(mob/living/carbon/H) - name = "[H]'s brain" +/obj/item/organ/internal/brain/proc/transfer_identity(mob/living/L) + name = "[L.name]'s brain" brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna - brainmob.timeofhostdeath = H.timeofdeath - if(H.mind) - H.mind.transfer_to(brainmob) + brainmob.name = L.real_name + brainmob.real_name = L.real_name + brainmob.timeofhostdeath = L.timeofdeath + if(iscarbon(L)) + var/mob/living/carbon/C = L + brainmob.dna = C.dna + if(L.mind) + L.mind.transfer_to(brainmob) brainmob << "You feel slightly disoriented. That's normal when you're just a brain." -/obj/item/organ/brain/examine(mob/user) +/obj/item/organ/internal/brain/examine(mob/user) ..() if(brainmob && brainmob.client) user << "You can feel the small spark of life still left in this one." @@ -42,7 +72,7 @@ user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later." -/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user) +/obj/item/organ/internal/brain/attack(mob/living/carbon/M, mob/user) if(!istype(M)) return ..() @@ -58,7 +88,7 @@ //since these people will be dead M != usr - if(!M.getorgan(/obj/item/organ/brain)) + if(!M.getorgan(/obj/item/organ/internal/brain)) user.drop_item() for(var/mob/O in viewers(M, null)) if(O == (user || M)) @@ -74,35 +104,18 @@ else user << "You insert [src] into your head." //LOL - //this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO - if(M.key) - M.ghostize() - - if(brainmob.mind) - brainmob.mind.transfer_to(M) - else - M.key = brainmob.key - - qdel(brainmob) - - M.internal_organs += src - loc = null - - //Update the body's icon so it doesnt appear debrained anymore - if(ishuman(M)) - H.update_hair(0) - + Insert(M) else ..() -/obj/item/organ/brain/alien - name = "alien brain" - desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" - icon_state = "brain-alien" - origin_tech = "biotech=7" - -/obj/item/organ/brain/Destroy() //copypasted from MMIs. +/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs. if(brainmob) qdel(brainmob) brainmob = null ..() + +/obj/item/organ/internal/brain/alien + name = "alien brain" + desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" + icon_state = "brain-alien" + origin_tech = "biotech=7" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index f97ddb1a3db..889c0826459 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -3,7 +3,7 @@ if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container. container.visible_message("[src]'s MMI flatlines!", \ "You hear something flatline.") - if(istype(src,/obj/item/organ/brain/alien)) + if(istype(src,/obj/item/organ/internal/brain/alien)) container.icon_state = "mmi_alien_dead" else container.icon_state = "mmi_dead" @@ -23,6 +23,6 @@ if(container && istype(container, /obj/item/device/mmi)) qdel(container)//Gets rid of the MMI if there is one if(loc) - if(istype(loc,/obj/item/organ/brain)) + if(istype(loc,/obj/item/organ/internal/brain)) qdel(loc)//Gets rid of the brain item ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index c9ff89d92bd..f2a6715af8e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -173,7 +173,7 @@ var/appears_dead = 0 if(stat == DEAD || (status_flags & FAKEDEATH)) appears_dead = 1 - if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain + if(getorgan(/obj/item/organ/internal/brain))//Only perform these checks if there is no brain if(suiciding) msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n" msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life" @@ -252,7 +252,7 @@ else if(getBrainLoss() >= 60) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if(getorgan(/obj/item/organ/brain)) + if(getorgan(/obj/item/organ/internal/brain)) if(istype(src,/mob/living/carbon/human/interactive)) msg += "[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.\n" else if(!key) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 658bd354c0c..795c7e68da7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -24,7 +24,7 @@ O.owner = src internal_organs += new /obj/item/organ/internal/appendix internal_organs += new /obj/item/organ/internal/heart - internal_organs += new /obj/item/organ/brain + internal_organs += new /obj/item/organ/internal/brain for(var/obj/item/organ/internal/I in internal_organs) I.Insert(src) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 12266289786..db366b79fb0 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -168,7 +168,7 @@ standing += img_facial_s //Applies the debrained overlay if there is no brain - if(!H.getorgan(/obj/item/organ/brain)) + if(!H.getorgan(/obj/item/organ/internal/brain)) standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER) if((H.wear_suit) && (H.wear_suit.hooded) && (H.wear_suit.suittoggled == 1)) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 8f6db5b5086..86014c735ca 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -261,7 +261,7 @@ if(..()) //alive - if(health <= config.health_threshold_dead || !getorgan(/obj/item/organ/brain)) + if(health <= config.health_threshold_dead || !getorgan(/obj/item/organ/internal/brain)) death() return diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 7a2a5379910..c04a2ccc65e 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -18,7 +18,7 @@ internal_organs += new /obj/item/organ/internal/appendix internal_organs += new /obj/item/organ/internal/heart - internal_organs += new /obj/item/organ/brain + internal_organs += new /obj/item/organ/internal/brain for(var/obj/item/organ/internal/I in internal_organs) I.Insert(src) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e37ec22d115..d430dc8ca55 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -106,7 +106,7 @@ //MMI stuff. Held togheter by magic. ~Miauw if(!mmi || !mmi.brainmob) mmi = new(src) - mmi.brain = new /obj/item/organ/brain(mmi) + mmi.brain = new /obj/item/organ/internal/brain(mmi) mmi.brain.name = "[real_name]'s brain" mmi.locked = 1 mmi.icon_state = "mmi_full" diff --git a/code/modules/surgery/appendectomy.dm b/code/modules/surgery/appendectomy.dm deleted file mode 100644 index 9355890cb5f..00000000000 --- a/code/modules/surgery/appendectomy.dm +++ /dev/null @@ -1,32 +0,0 @@ -/datum/surgery/appendectomy - name = "appendectomy" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/extract_appendix, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - possible_locs = list("groin") - - -//extract appendix -/datum/surgery_step/extract_appendix - name = "extract appendix" - accept_hand = 1 - time = 64 - var/obj/item/organ/internal/appendix/A = null - -/datum/surgery_step/extract_appendix/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - A = locate() in target.internal_organs - if(A) - user.visible_message("[user] begins to extract [target]'s appendix.", "You begin to extract [target]'s appendix...") - else - user.visible_message("[user] looks for an appendix in [target].", "You look for an appendix in [target]...") - -/datum/surgery_step/extract_appendix/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(A) - user.visible_message("[user] successfully removes [target]'s appendix!", "You successfully removes [target]'s appendix.") - A.loc = get_turf(target) - A.Remove(target) - for(var/datum/disease/appendicitis in target.viruses) - appendicitis.cure() - target.resistances += /datum/disease/appendicitis - else - user << "You can't find an appendix in [target]!" - return 1 diff --git a/code/modules/surgery/brain_removal.dm b/code/modules/surgery/brain_removal.dm deleted file mode 100644 index 0d2426775a6..00000000000 --- a/code/modules/surgery/brain_removal.dm +++ /dev/null @@ -1,43 +0,0 @@ -/datum/surgery/brain_removal - name = "brain removal" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/extract_brain) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - possible_locs = list("head") - requires_organic_bodypart = 0 - - -//extract brain -/datum/surgery_step/extract_brain - name = "extract brain" - implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 55) - time = 64 - var/obj/item/organ/brain/B = null - -/datum/surgery_step/extract_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - B = target.getorgan(/obj/item/organ/brain) - if(B) - user.visible_message("[user] begins to extract [target]'s brain.", "You begin to extract [target]'s brain...") - else - user.visible_message("[user] looks for a brain in [target].", "You look for a brain in [target]...") - -/datum/surgery_step/extract_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(B) - user.visible_message("[user] successfully removes [target]'s brain!", "You successfully remove [target]'s brain.") - B.loc = get_turf(target) - B.transfer_identity(target) - target.internal_organs -= B - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.update_hair(0) - H.apply_damage(25,"brute","head") - add_logs(user, target, "debrained", addition="INTENT: [uppertext(user.a_intent)]") - else - user << "You can't find a brain in [target]!" - return 1 - - -//brain removal for aliens -/datum/surgery/brain_removal/alien - name = "alien brain removal" - steps = list(/datum/surgery_step/saw, /datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/extract_brain) - species = list(/mob/living/carbon/alien/humanoid) diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm index fe976b25824..4f872f6c047 100644 --- a/code/modules/surgery/core_removal.dm +++ b/code/modules/surgery/core_removal.dm @@ -2,8 +2,11 @@ name = "core removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/incise, /datum/surgery_step/extract_core) species = list(/mob/living/simple_animal/slime) - target_must_be_dead = 1 +/datum/surgery/core_removal/can_start(mob/user, mob/living/carbon/target) + if(target.stat == DEAD) + return 1 + return 0 //extract brain /datum/surgery_step/extract_core diff --git a/code/modules/surgery/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm deleted file mode 100644 index ed6813bf087..00000000000 --- a/code/modules/surgery/cybernetic_implants.dm +++ /dev/null @@ -1,80 +0,0 @@ -#define MAX_BRAIN_IMPLANT 2 -#define MAX_CHEST_IMPLANT 3 - -/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/implant, datum/surgery/surgery) - user.visible_message("[user] begins to implant [target] with [implant].", "You begin to implant [target] with [implant]...") - -//[[[[EYES]]]] -/datum/surgery/cybernetic_implant/eyes - name = "eye cybernetic implant" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/cybernetic_implant/eyes, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) - possible_locs = list("eyes") - -/datum/surgery_step/cybernetic_implant/eyes - name = "insert eye cybernetic implant" - implements = list(/obj/item/organ/internal/cyberimp/eyes = 100) - time = 32 - -/datum/surgery_step/cybernetic_implant/eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/eyes/implant, datum/surgery/surgery) - if(implant) - var/full = 0 - if(locate(/obj/item/organ/internal/cyberimp/eyes, target.internal_organs)) - full = 1 - insert(user,target,implant,target_zone,full) - return 1 - -//[[[[BRAIN]]]] -/datum/surgery/cybernetic_implant/brain - name = "brain cybernetic implant" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/brain, /datum/surgery_step/close) - possible_locs = list("head") - requires_organic_bodypart = 0 - -/datum/surgery_step/cybernetic_implant/brain - name = "insert brain cybernetic implant" - implements = list(/obj/item/organ/internal/cyberimp/brain = 100) - time = 32 - -/datum/surgery_step/cybernetic_implant/brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/brain/implant, datum/surgery/surgery) - if(implant) - var/full = 0 - for(var/obj/item/I in target.internal_organs) - if(istype(I,/obj/item/organ/internal/cyberimp/brain)) - full++ - - if(full < MAX_BRAIN_IMPLANT) - full = 0 - insert(user,target,implant,target_zone,full) - return 1 - -//[[[[CHEST]]]] -/datum/surgery/cybernetic_implant/chest - name = "torso cybernetic implant" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/chest, /datum/surgery_step/close) - possible_locs = list("chest") - requires_organic_bodypart = 0 - -/datum/surgery_step/cybernetic_implant/chest - name = "insert torso cybernetic implant" - implements = list(/obj/item/organ/internal/cyberimp/chest = 100) - time = 32 - -/datum/surgery_step/cybernetic_implant/chest/success(mob/user, mob/living/carbon/target, target_zone, obj/item/organ/internal/cyberimp/chest/implant, datum/surgery/surgery) - if(implant) - var/full = 0 - for(var/obj/item/I in target.internal_organs) - if(istype(I,/obj/item/organ/internal/cyberimp/chest)) - full++ - if(full < MAX_CHEST_IMPLANT) - full = 0 - - insert(user,target,implant,target_zone,full) - return 1 - -/datum/surgery_step/cybernetic_implant/proc/insert(mob/user, mob/living/carbon/target, obj/item/organ/internal/cyberimp/implant,target_zone,full) - if(full) - user << "You can't seem to implant anything else into the [target]'s [target_zone]!" - else - user.visible_message("[user] inserts [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone]!", "You insert [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone].") - user.drop_item() - implant.Insert(target) \ No newline at end of file diff --git a/code/modules/surgery/dethrall.dm b/code/modules/surgery/dethrall.dm index bd54a7f3f6f..c421e8ece6e 100644 --- a/code/modules/surgery/dethrall.dm +++ b/code/modules/surgery/dethrall.dm @@ -3,14 +3,17 @@ steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/dethrall) possible_locs = list("head") +/datum/surgery/dethrall/can_start(mob/user, mob/living/carbon/target) + return is_thrall(target) + /datum/surgery_step/dethrall name = "search head" accept_hand = 1 time = 70 - var/obj/item/organ/brain/B = null + var/obj/item/organ/internal/brain/B = null /datum/surgery_step/dethrall/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - B = target.getorgan(/obj/item/organ/brain) + B = target.getorgan(/obj/item/organ/internal/brain) if(B) user.visible_message("[user] begins looking around in [target]'s head.", "You begin looking for foreign influences on [target]'s brain...") @@ -19,8 +22,6 @@ if(!is_thrall(target)) user << "You are unable to locate anything on [target]'s brain." return 1 - user << "You locate a small, pulsing black tumor on the side of [target]'s brain and begin to remove it." - target << "A small part of your head pulses with agony as the light impacts it." sleep(30) user.visible_message("[user] begins removing something from [target]'s head.", \ "You begin carefully extracting the tumor...") diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 06117fb80d7..83821b42e1d 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -23,7 +23,7 @@ return 1 /datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(target.getorgan(/obj/item/organ/brain)) + if(target.getorgan(/obj/item/organ/internal/brain)) user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!") target.adjustBrainLoss(100) else diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/generic_steps.dm index 1f01549e999..351e2eec06a 100644 --- a/code/modules/surgery/generic_steps.dm +++ b/code/modules/surgery/generic_steps.dm @@ -3,7 +3,7 @@ /datum/surgery_step/incise name = "make incision" implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/kitchen/knife = 65, /obj/item/weapon/shard = 45) - time = 24 + time = 16 /datum/surgery_step/incise/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to make an incision in [target]'s [parse_zone(target_zone)].", "You begin to make an incision in [target]'s [parse_zone(target_zone)]...") @@ -14,7 +14,7 @@ /datum/surgery_step/clamp_bleeders name = "clamp bleeders" implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/wirecutters = 60, /obj/item/stack/cable_coil = 15) - time = 48 + time = 24 /datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to clamp bleeders in [target]'s [parse_zone(target_zone)].", "You begin to clamp bleeders in [target]'s [parse_zone(target_zone)]...") @@ -29,7 +29,7 @@ /datum/surgery_step/retract_skin name = "retract skin" implements = list(/obj/item/weapon/retractor = 100, /obj/item/weapon/screwdriver = 45, /obj/item/weapon/wirecutters = 35) - time = 32 + time = 24 /datum/surgery_step/retract_skin/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].", "You begin to retract the skin in [target]'s [parse_zone(target_zone)]...") @@ -40,7 +40,7 @@ /datum/surgery_step/close name = "mend incision" implements = list(/obj/item/weapon/cautery = 100, /obj/item/weapon/weldingtool = 70, /obj/item/weapon/lighter = 45, /obj/item/weapon/match = 20) - time = 32 + time = 24 /datum/surgery_step/close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].", "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...") @@ -75,7 +75,7 @@ /datum/surgery_step/saw name = "saw bone" implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchen/knife/butcher = 25) - time = 64 + time = 54 /datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].", "You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...") diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 021eddeb277..f3bbee0b6c9 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -33,7 +33,7 @@ break var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries - if(P && user.Adjacent(M) && (I in user)) + if(P && user && user.Adjacent(M) && (I in user)) var/datum/surgery/S = available_surgeries[P] var/datum/surgery/procedure = new S.type if(procedure) diff --git a/code/modules/surgery/limb augmentation.dm b/code/modules/surgery/limb augmentation.dm index d7ff7340302..fc8e72bdb75 100644 --- a/code/modules/surgery/limb augmentation.dm +++ b/code/modules/surgery/limb augmentation.dm @@ -61,11 +61,10 @@ if("head") H.organs += new /obj/item/organ/limb/robot/head(src) if("chest") - var/datum/surgery_step/xenomorph_removal/xeno_removal = new - xeno_removal.remove_xeno(user, target) // remove an alien if there is one - H.organs += new /obj/item/organ/limb/robot/chest(src) - for(var/datum/disease/appendicitis/A in H.viruses) //If they already have Appendicitis, Remove it - A.cure(1) + for(var/obj/item/organ/internal/I in target.getorganszone(target_zone, 1)) + if(I.status == ORGAN_ORGANIC) // FLESH IS WEAK + I.Remove(target, special = 1) + qdel(I) user.drop_item() qdel(tool) H.update_damage_overlays(0) diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm new file mode 100644 index 00000000000..30ea86e3ea6 --- /dev/null +++ b/code/modules/surgery/organ_manipulation.dm @@ -0,0 +1,111 @@ +/datum/surgery/organ_manipulation + name = "organ manipulation" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/saw, + /datum/surgery_step/manipulate_organs, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/close) + species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list("chest", "head") + requires_organic_bodypart = 0 + +/datum/surgery/organ_manipulation/soft + possible_locs = list("groin", "eyes", "mouth") + steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, + /datum/surgery_step/manipulate_organs, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/close) + +/datum/surgery/organ_manipulation/alien + name = "alien organ manipulation" + possible_locs = list("chest", "head", "groin", "eyes", "mouth") + species = list(/mob/living/carbon/alien/humanoid) + steps = list(/datum/surgery_step/saw, /datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/manipulate_organs) + + + + +/datum/surgery_step/manipulate_organs + time = 64 + name = "manipulate organs" + implements = list(/obj/item/organ/internal = 100) + var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 55) + var/implements_mend = list(/obj/item/weapon/cautery = 100, /obj/item/weapon/weldingtool = 70, /obj/item/weapon/lighter = 45, /obj/item/weapon/match = 20) + var/current_type + var/obj/item/organ/internal/I = null + +/datum/surgery_step/manipulate_organs/New() + ..() + implements = implements + implements_extract + implements_mend + +/datum/surgery_step/manipulate_organs/tool_check(mob/user, obj/item/tool) + if(istype(tool, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = tool + if(!WT.isOn()) return 0 + + else if(istype(tool, /obj/item/weapon/lighter)) + var/obj/item/weapon/lighter/L = tool + if(!L.lit) return 0 + + else if(istype(tool, /obj/item/weapon/match)) + var/obj/item/weapon/match/M = tool + if(!M.lit) return 0 + + return 1 + + +/datum/surgery_step/manipulate_organs/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + I = null + if(isorgan(tool)) + current_type = "insert" + I = tool + if(target_zone != I.zone || target.getorganslot(I.slot)) + user << "There is no room for [I] in [target]'s [parse_zone(target_zone)]!" + return -1 + + user.visible_message("[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].", + "You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...") + + else if(implement_type in implements_extract) + current_type = "extract" + var/list/organs = target.getorganszone(target_zone) + if(!organs.len) + user << "There is no removeable organs in [target]'s [parse_zone(target_zone)]!" + return -1 + else + for(var/obj/item/organ/internal/O in organs) + O.on_find(user) + organs -= O + organs[O.name] = O + + I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs + if(I && user && target && user.Adjacent(target) && user.get_active_hand() == tool) + I = organs[I] + if(!I) return -1 + user.visible_message("[user] begins to extract [I] from [target]'s [parse_zone(target_zone)].", + "You begin to extract [I] from [target]'s [parse_zone(target_zone)]...") + else + return -1 + + else if(implement_type in implements_mend) + current_type = "mend" + + +/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(current_type == "mend") + user.visible_message("[user] mend the incision in [target]'s [parse_zone(target_zone)].", + "You mend the incision in [target]'s [parse_zone(target_zone)].") + return 1 + else if(current_type == "insert") + I = tool + user.drop_item() + I.Insert(target) + user.visible_message("[user] inserts [tool] into [target]'s [parse_zone(target_zone)]!", + "You insert [tool] into [target]'s [parse_zone(target_zone)].") + + else if(current_type == "extract") + if(I && I.owner == target) + user.visible_message("[user] successfully extracts [I] from [target]'s [parse_zone(target_zone)]!", + "You successfully extract [I] from [target]'s [parse_zone(target_zone)].") + add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") + I.Remove(target) + I.loc = get_turf(target) + else + user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", + "You can't extract anything from [target]'s [parse_zone(target_zone)]!") + return 0 \ No newline at end of file diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index 18b4185ea52..a3f8d5de65b 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -11,8 +11,16 @@ mob/proc/getorganslot(slot) mob/living/carbon/getorgan(typepath) return (locate(typepath) in internal_organs) -mob/living/carbon/getorganszone(zone) +mob/living/carbon/getorganszone(zone, var/subzones = 0) var/list/returnorg = list() + if(subzones) + if(zone == "head") + returnorg = getorganszone("eyes") + getorganszone("mouth") + // We don't have mouth organs now, but who knows? + if(zone == "chest") + returnorg = getorganszone("groin") + + for(var/obj/item/organ/internal/O in internal_organs) if(zone == O.zone) returnorg += O diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index ae4e1e00a55..f37761f55a2 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -1,12 +1,15 @@ /obj/item/organ/internal origin_tech = "biotech=2" + force = 1 + w_class = 2 + throwforce = 0 var/zone = "chest" var/slot var/vital = 0 var/organ_action_name = null -/obj/item/organ/internal/proc/Insert(var/mob/living/carbon/M, special = 0) - if(!iscarbon(M) || owner) +/obj/item/organ/internal/proc/Insert(mob/living/carbon/M, special = 0) + if(!iscarbon(M) || owner == M) return var/obj/item/organ/internal/replaced = M.getorganslot(slot) @@ -19,7 +22,8 @@ if(organ_action_name) action_button_name = organ_action_name -/obj/item/organ/internal/proc/Remove(var/mob/living/carbon/M, special = 0) + +/obj/item/organ/internal/proc/Remove(mob/living/carbon/M, special = 0) owner = null if(M) M.internal_organs -= src @@ -29,14 +33,42 @@ 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/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 + S.reagents.add_reagent("nutriment", 5) + + return S + /obj/item/organ/internal/Destroy() if(owner) Remove(owner, 1) ..() +/obj/item/organ/internal/attack(mob/living/carbon/M, mob/user) + if(M == user && ishuman(user)) + var/mob/living/carbon/human/H = user + if(status == ORGAN_ORGANIC) + var/obj/item/weapon/reagent_containers/food/snacks/S = prepare_eat() + if(S) + H.drop_item() + H.put_in_active_hand(S) + S.attack(H, H) + qdel(src) + else + ..() + //Looking for brains? //Try code/modules/mob/living/carbon/brain/brain_item.dm @@ -57,17 +89,23 @@ else icon_state = "heart-off" -/obj/item/organ/internal/heart/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/internal/heart/Insert(mob/living/carbon/M, special = 0) ..() beating = 1 update_icon() -/obj/item/organ/internal/heart/Remove(var/mob/living/carbon/M, special = 0) +/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/appendix name = "appendix" @@ -84,12 +122,20 @@ icon_state = "appendix" name = "appendix" -/obj/item/organ/internal/appendix/Remove(var/mob/living/carbon/M, special = 0) - for(var/datum/disease/appendicitis in M.viruses) - appendicitis.cure() +/obj/item/organ/internal/appendix/Remove(mob/living/carbon/M, special = 0) + for(var/datum/disease/appendicitis/A in M.viruses) + A.cure() + inflamed = 1 + update_icon() ..() -/obj/item/organ/internal/appendix/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/internal/appendix/Insert(mob/living/carbon/M, special = 0) ..() if(inflamed) - M.AddDisease(new /datum/disease/appendicitis) \ No newline at end of file + M.AddDisease(new /datum/disease/appendicitis) + +/obj/item/organ/internal/appendix/prepare_eat() + var/obj/S = ..() + if(inflamed) + S.reagents.add_reagent("????", 5) + return S \ No newline at end of file diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 9a9196562fd..0801896b63a 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -5,7 +5,6 @@ var/step_in_progress = 0 //Actively performing a Surgery var/list/species = list(/mob/living/carbon/human) //Acceptable Species var/location = "chest" //Surgery location - var/target_must_be_dead = 0 //Needs to be dead var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs var/list/possible_locs = list() //Multiple locations -- c0 var/ignore_clothes = 0 //This surgery ignores clothes diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index bd442c7c5a7..0b9c9980668 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -38,9 +38,11 @@ /datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) surgery.step_in_progress = 1 - preop(user, target, target_zone, tool, surgery) - if(do_after(user, time, target = target)) + if(preop(user, target, target_zone, tool, surgery) == -1) + surgery.step_in_progress = 0 + return + if(do_after(user, time, target = target)) var/advance = 0 var/prob_chance = 100 diff --git a/code/modules/surgery/xenomorph_removal.dm b/code/modules/surgery/xenomorph_removal.dm deleted file mode 100644 index 97cabb6d003..00000000000 --- a/code/modules/surgery/xenomorph_removal.dm +++ /dev/null @@ -1,50 +0,0 @@ -/datum/surgery/xenomorph_removal - name = "xenomorph removal" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/xenomorph_removal, /datum/surgery_step/close) - species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - possible_locs = list("chest") - - - -//remove xeno from premises -/datum/surgery_step/xenomorph_removal - name = "remove foregin body" - implements = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/shovel/spade = 65, /obj/item/weapon/cultivator = 50, /obj/item/weapon/crowbar = 35) - time = 64 - -/datum/surgery_step/xenomorph_removal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to search in [target]'s chest for a xenomorph embryo.", "You begin to search in [target]'s chest for a xenomorph embryo...") - -/datum/surgery_step/xenomorph_removal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(remove_xeno(user, target)) - user.visible_message("[user] successfully extracts the xenomorph embryo from [target]!", "You successfully extract the xenomorph embryo from [target].") - else - user.visible_message("[user] can't seem to find anything in [target]'s chest!", "You can't find anything in [target]'s chest!") - return 1 - -/datum/surgery_step/xenomorph_removal/proc/remove_xeno(mob/user, mob/living/carbon/target) - var/obj/item/organ/internal/body_egg/alien_embryo/A = target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) - if(A) - user << "You found an unknown alien organism in [target]'s chest!" - if(A.stage < 4) - user << "It's small and weak, barely the size of a foetus." - else - user << "It's grown quite large, and writhes slightly as you look at it." - if(prob(10)) - A.AttemptGrow() - - A.Remove(target) - A.loc = get_turf(target) - return 1 - - -/datum/surgery_step/xenomorph_removal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - var/obj/item/organ/internal/body_egg/alien_embryo/A = target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) - if(A) - if(prob(50)) - A.AttemptGrow(0) - user.visible_message("[user] accidentally pokes the xenomorph in [target]!", "You accidentally poke the xenomorph in [target]!") - else - target.adjustOxyLoss(30) - user.visible_message("[user] accidentally pokes [target] in the lungs!", "You accidentally poke [target] in the lungs!") - return 0 \ No newline at end of file diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index e3a0165745fc76155005a23a4283284b9320bae0..e1f7fe92119e3f84413aae1dc68b7a93dab0f106 100644 GIT binary patch literal 13088 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 literal 12861 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