From 948adea83b49e8e19c237fa49962cfee99c878c7 Mon Sep 17 00:00:00 2001 From: Aurorablade Date: Mon, 4 Jan 2016 08:25:39 -0500 Subject: [PATCH] Added Asses as an organ ...made you look... seriously though, refined some surgery datums/steps and commiting so i can go bugfix some stuff...and a sidequest...i need to adjust return values. --- code/_onclick/item_attack.dm | 6 +- code/game/objects/items/stacks/medical.dm | 30 +- code/game/objects/items/stacks/nanopaste.dm | 6 +- code/game/objects/items/weapons/kitchen.dm | 4 +- code/modules/client/preferences.dm | 2 +- code/modules/hydroponics/grown.dm | 2 +- .../carbon/alien/special/alien_embryo.dm | 108 +++---- .../mob/living/carbon/human/update_icons.dm | 6 +- code/modules/reagents/reagent_containers.dm | 8 +- code/modules/surgery/helpers.dm | 21 +- code/modules/surgery/organs_internal.dm | 25 +- code/modules/surgery/robotics.dm | 298 +++++++++++------- code/modules/surgery/surgery.dm | 43 ++- 13 files changed, 331 insertions(+), 228 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 9ab4aa159d0..22c85ec85b0 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -30,9 +30,9 @@ return 0 var/messagesource = M - if (can_operate(M)) //Checks if mob is lying down on table for surgery - if (do_surgery(M,user,src)) - return 0 + //if (can_operate(M)) //Checks if mob is lying down on table for surgery + // if (do_surgery(M,user,src)) + // return 0 if (istype(M,/mob/living/carbon/brain)) messagesource = M:container diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 83043ed7770..d6197c416a6 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -112,11 +112,11 @@ affecting.heal_damage(src.heal_brute, src.heal_burn, 0) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than some ointment!" + //if (can_operate(H)) //Checks if mob is lying down on table for surgery + // if (do_surgery(H,user,src)) + // return + //else + user << "The [affecting.name] is cut open, you'll need more than some ointment!" /obj/item/stack/medical/bruise_pack/comfrey name = "\improper Comfrey leaf" @@ -177,11 +177,11 @@ affecting.heal_damage(heal_brute,0) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + //if (can_operate(H)) //Checks if mob is lying down on table for surgery + // if (do_surgery(H,user,src)) + // return + //else + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/advanced/ointment name = "advanced burn kit" @@ -210,11 +210,11 @@ affecting.heal_damage(0,heal_burn) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + //if (can_operate(H)) //Checks if mob is lying down on table for surgery + // if (do_surgery(H,user,src)) + // return + //else + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/splint name = "medical splints" diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index fea0281c9b8..7da3d2935ba 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -27,9 +27,9 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(can_operate(H)) - if (do_surgery(H,user,src)) - return + //if(can_operate(H)) + // if (do_surgery(H,user,src)) + // return if (S && (S.status & ORGAN_ROBOT)) if(S.get_damage()) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 64a5ad53948..2fbd6589562 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -63,8 +63,8 @@ overlays.Cut() return - if (can_operate(M)) - do_surgery(M, user, src) + //if (can_operate(M)) + // do_surgery(M, user, src) /obj/item/weapon/kitchen/utensil/fork name = "fork" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index bc28c88ee2f..7a0f81b3bb4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1565,7 +1565,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else O.robotize() else - var/obj/item/organ/I = character.internal_organs_by_name[name] + var/obj/item/organ/internal/I = character.get_int_organ(name) if(I) if(status == "assisted") I.mechassist() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index b39ca263d02..2704ef7dded 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -298,7 +298,7 @@ // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely. // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z - if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0 + if(!istype(M)) return 0 if(!def_zone) def_zone = check_zone(user.zone_sel.selecting) 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 5ffe45a8123..d56593f2206 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -2,7 +2,7 @@ // It functions almost identically (see code/datums/diseases/alien_embryo.dm) var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/alien_embryo +/obj/item/organ/internal/body_egg/alien_embryo name = "alien embryo" desc = "All slimy and yuck." icon = 'icons/mob/alien.dmi' @@ -10,30 +10,49 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds var/mob/living/affected_mob var/stage = 0 -/obj/item/alien_embryo/New() - if(istype(loc, /mob/living)) - affected_mob = loc - affected_mob.status_flags |= XENO_HOST - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - processing_objects.Add(src) - spawn(0) - AddInfectionImages(affected_mob) +/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 - qdel(src) + finder << "It's grown quite large, and writhes slightly as you look at it." + if(prob(10)) + AttemptGrow(0) -/obj/item/alien_embryo/Destroy() - if(affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - RemoveInfectionImages(affected_mob) - return ..() +/obj/item/organ/internal/body_egg/alien_embryo/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("sacid", 10) + return S -/obj/item/alien_embryo/process() +/obj/item/organ/internal/body_egg/alien_embryo/on_life() + switch(stage) + if(2, 3) + if(prob(2)) + owner.emote("sneeze") + 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(4)) + owner << "Your stomach hurts." + if(prob(20)) + owner.adjustToxLoss(1) + if(5) + owner << "You feel something tearing its way out of your stomach..." + owner.adjustToxLoss(10) + +/obj/item/organ/internal/body_egg/alien_embryo/egg_process() if(!affected_mob) return if(loc != affected_mob) affected_mob.status_flags &= ~(XENO_HOST) @@ -51,38 +70,15 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds spawn(0) RefreshInfectionImage() - switch(stage) - if(2, 3) - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - affected_mob << "Your throat feels sore." - if(prob(1)) - affected_mob << "Mucous runs down the back of your throat." - if(4) - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(2)) - affected_mob << "Your muscles ache." - if(prob(20)) - affected_mob.take_organ_damage(1) - if(prob(2)) - affected_mob << "Your stomach hurts." - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - if(5) - affected_mob << "You feel something tearing its way out of your stomach..." - affected_mob.adjustToxLoss(10) - affected_mob.updatehealth() - if(prob(50)) - AttemptGrow() -/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) + if(stage == 5 && prob(50)) + //for(var/datum/surgery/S in owner.surgeries) + // if(S.location == "chest" && istype(S.get_surgery_step(), /datum/surgery_step/manipulate_organs)) + // AttemptGrow(0) + // return + AttemptGrow() + +/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) var/list/candidates = get_candidates(ROLE_ALIEN,ALIEN_AFK_BRACKET,1) var/client/C = null @@ -123,7 +119,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds Proc: RefreshInfectionImage() Des: Removes the current icons located in the infected mob adds the current stage ----------------------------------------*/ -/obj/item/alien_embryo/proc/RefreshInfectionImage() +/obj/item/organ/internal/body_egg/alien_embryo/RefreshInfectionImage() RemoveInfectionImages() AddInfectionImages() @@ -131,7 +127,7 @@ Des: Removes the current icons located in the infected mob adds the current stag Proc: AddInfectionImages(C) Des: Adds the infection image to all aliens for this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/AddInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/AddInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) var/I = image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "infected[stage]") @@ -141,7 +137,7 @@ Des: Adds the infection image to all aliens for this embryo Proc: RemoveInfectionImage(C) Des: Removes all images from the mob infected by this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/RemoveInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/RemoveInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) for(var/image/I in alien.client.images) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index faa638f401e..b768039ac29 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -381,6 +381,9 @@ var/global/list/damage_icon_parts = list() else //warning("Invalid f_style for [species.name]: [f_style]") + if(!get_int_organ(/obj/item/organ/internal/brain)) + face_standing += icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s") + if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] if(hair_style && hair_style.species_allowed) @@ -393,9 +396,6 @@ var/global/list/damage_icon_parts = list() else //warning("Invalid h_style for [species.name]: [h_style]") - if(!get_int_organ(/obj/item/organ/internal/brain)) - face_standing += icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s") - overlays_standing[HAIR_LAYER] = image(face_standing) if(update_icons) update_icons() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 7f9c3ee3c98..3fa08e42a03 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -46,10 +46,10 @@ /obj/item/weapon/reagent_containers/attack_self(mob/user as mob) return -/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone) - if (can_operate(M)) //Checks if mob is lying down on table for surgery - if (do_surgery(M,user,src)) - return +///obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone) +// if (can_operate(M)) //Checks if mob is lying down on table for surgery +// if (do_surgery(M,user,src)) +// return // this prevented pills, food, and other things from being picked up by bags. // possibly intentional, but removing it allows us to not duplicate functionality. diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 9340099a1bb..52d68c4fbd7 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -1,46 +1,61 @@ /proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user) + world << "[istype(M)]" if(istype(M)) var/mob/living/carbon/human/H var/obj/item/organ/external/affecting var/selected_zone = user.zone_sel.selecting - + world << "line 8" if(istype(M, /mob/living/carbon/human)) H = M + world <<"line 10" affecting = H.get_organ(check_zone(selected_zone)) - if(can_operate(M)) //if they're prone or a slime + if(can_operate(H)) //if they're prone or a slime var/datum/surgery/current_surgery + world << "line 15" for(var/datum/surgery/S in M.surgeries) if(S.location == selected_zone) current_surgery = S + world << "[S]" if(!current_surgery) var/list/all_surgeries = surgeries_list.Copy() var/list/available_surgeries = list() + world << "line 24" for(var/datum/surgery/S in all_surgeries) if(!S.possible_locs.Find(selected_zone)) + world << "line 29" + world << "[selected_zone]" continue if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOT) + world << "line 30" continue if(!S.can_start(user, M)) + world << "line 31" continue for(var/path in S.allowed_species) + world << "[path]" + world << "[M]" if(istype(M, path)) + world << "line 32" + world << "[path]" available_surgeries[S.name] = S break var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries if(P && user && user.Adjacent(M) && (I in user)) + world << "line 40" var/datum/surgery/S = available_surgeries[P] var/datum/surgery/procedure = new S.type if(procedure) procedure.location = selected_zone M.surgeries += procedure procedure.organ_ref = affecting - //just use the scalpel cut message + user.visible_message("[user] prepares to operate on [M]'s [parse_zone(selected_zone)].", \ + "You prepare to operate on [M]'s [parse_zone(selected_zone)].") else if(!current_surgery.step_in_progress) if(current_surgery.status == 1) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 0e18d6a357c..6e9d1228ecd 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -125,12 +125,8 @@ var/obj/item/organ/internal/body_egg/alien_embryo/A = target.get_int_organ(/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() + if(prob(10)) + A.AttemptGrow() A.remove(target) A.loc = get_turf(target) @@ -154,7 +150,7 @@ allowed_tools = list(/obj/item/organ/internal = 100, /obj/item/weapon/reagent_containers/food/snacks/organ = 0) var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 55) - var/implements_mend = list(/obj/item/stack/medical/advanced/bruise_pack= 100,/obj/item/stack/medical/bruise_pack = 20 + var/implements_mend = list(/obj/item/stack/medical/advanced/bruise_pack= 100,/obj/item/stack/nanopaste = 100,/obj/item/stack/medical/bruise_pack = 20 ) var/current_type var/obj/item/organ/internal/I = null @@ -222,16 +218,21 @@ tool_name = "regenerative membrane" else if (istype(tool, /obj/item/stack/medical/bruise_pack)) tool_name = "the bandaid" + else if (istype(tool, /obj/item/stack/nanopaste)) + tool_name = "\the [tool]" //what else do you call nanopaste medically? if (!hasorgans(target)) return for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic < 2) + if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) if(!I.sterile) spread_germs_to_organ(I, user) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) + else if(I.robotic > 2 && istype(tool, /obj/item/stack/nanopaste)) + user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ + "You start treating damage to [target]'s [I.name] with [tool_name]." ) target.custom_pain("The pain in your [affected.name] is living hell!",1) else if(istype(tool, /obj/item/weapon/reagent_containers/food/snacks/organ)) @@ -253,7 +254,11 @@ if(I) I.surgeryize() if(I && I.damage > 0) - if(I.robotic < 2) + if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) + user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ + "\blue You treat damage to [target]'s [I.name] with [tool_name]." ) + I.damage = 0 + else if(I.robotic > 2 && istype (tool, /obj/item/stack/nanopaste)) user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ "\blue You treat damage to [target]'s [I.name] with [tool_name]." ) I.damage = 0 @@ -282,7 +287,7 @@ 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 - ..() + ////////////////////////////////////////////////////////////////// // CHEST INTERNAL ORGAN SURGERY // diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 2a8fb4758e1..d0fe89dcd41 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -5,10 +5,17 @@ /datum/surgery/cybernetic_repair name = "Cybernetic Repair" - steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/fix_organ_robotic,/datum/surgery_step/robotics/external/close_hatch) + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/external/repair_brute,/datum/surgery_step/robotics/external/repair_burn,/datum/surgery_step/robotics/external/close_hatch) possible_locs = list("chest","head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") requires_organic_bodypart = 0 +/datum/surgery/cybernetic_repair + name = "Cybernetic Mainpulation" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/manipulate_robotic_organs) + possible_locs = list("chest","head","groin") + requires_organic_bodypart = 0 + + //to do, moar surgerys or condense down ala mainpulate organs. /datum/surgery_step/robotics can_infect = 0 @@ -214,31 +221,122 @@ "\red You cause a short circuit in [target]'s [affected.name]!") target.apply_damage(rand(5,10), BURN, affected) -/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs - allowed_tools = list( - /obj/item/stack/nanopaste = 100, \ - /obj/item/weapon/bonegel = 30, \ - /obj/item/weapon/screwdriver = 70, \ - ) +///////condenseing remove/extract/repair here. ///////////// +/datum/surgery_step/robotics/manipulate_robotic_organs + allowed_tools = list(/obj/item/device/mmi = 100) + var/implements_extract = list(/obj/item/device/multitool = 100) + var/implements_mend = list( /obj/item/stack/nanopaste = 100,/obj/item/weapon/bonegel = 30, /obj/item/weapon/screwdriver = 70) + var/implements_insert = list(/obj/item/weapon/screwdriver = 100) + var/current_type + var/obj/item/organ/internal/I = null + var/obj/item/organ/external/affected = null min_duration = 70 max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) +/datum/surgery_step/robotics/manipulate_robotic_organs/New() + ..() + allowed_tools = allowed_tools + implements_extract + implements_mend + implements_insert - if (!hasorgans(target)) - return - 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) - if(I.damage > 0 && I.robotic >= 2) - is_organ_damaged = 1 - break - return affected.open_enough_for_surgery() && is_organ_damaged - begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + +/datum/surgery_step/robotics/manipulate_robotic_organs/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + + I = null + affected = target.get_organ(target_zone) + if(tool in implements_insert) + current_type = "insert" + //I = tool + var/off_tool = user.get_inactive_hand() + + if(!off_tool || !istype(off_tool,/obj/item/organ/internal)) + user << "You need a replacement internal part in your off hand." + return -1 + I = off_tool //and please god let it be an organ... + if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) + user << "There is no room for [I] in [target]'s [parse_zone(target_zone)]!" + return -1 + + if(I.damage > (I.max_damage * 0.75)) + user << " \The [I] is in no state to be transplanted." + return -1 + + if(target.get_int_organ(I)) + user << "\red \The [target] already has [I]." + return -1 + + user.visible_message("[user] begins reattaching [target]'s [tool] with \the [tool].", \ + "You start reattaching [target]'s [surgery.current_organ] with \the [tool].") + target.custom_pain("Someone's rooting around in your [affected.name]!",1) + else if(istype(tool,/obj/item/device/mmi/)) + current_type = "install" + + if(target_zone != "chest") + user << " You must target the chest cavity." + + return -1 + var/obj/item/device/mmi/M = tool + + + if(!(affected && affected.open_enough_for_surgery())) + return -1 + + if(!istype(M)) + return -1 + + if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) + user << "That brain is not usable." + return -1 + + if(!(affected.status & ORGAN_ROBOT)) + user << "You cannot install a computer brain into a meat enclosure." + return -1 + + if(!target.species) + user << "You have no idea what species this person is. Report this on the bug tracker." + return -1 + + if(!target.species.has_organ["brain"]) + user << "You're pretty sure [target.species.name_plural] don't normally have a brain." + return -1 + + if(target.get_int_organ(/obj/item/organ/internal/brain/)) + user << "Your subject already has a brain." + return -1 + + user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ + "You start installing \the [tool] into [target]'s [affected.name].") + + else if(tool in implements_extract) + current_type = "extract" + var/list/organs = target.get_organs_zone(target_zone) + if(!(affected && (affected.status & ORGAN_ROBOT))) + return -1 + if(!affected.open_enough_for_surgery()) + return -1 + 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] starts to decouple [target]'s [I] with \the [tool].", \ + "You start to decouple [target]'s [I] with \the [tool]." ) + + target.custom_pain("The pain in your [affected.name] is living hell!",1) + else + return -1 + + else if(tool in implements_mend) + current_type = "mend" if (!hasorgans(target)) return var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -250,24 +348,69 @@ "You start mending the damage to [target]'s [I.name]'s mechanisms." ) target.custom_pain("The pain in your [affected.name] is living hell!",1) - ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + ..() + +/datum/surgery_step/robotics/manipulate_robotic_organs/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(current_type == "mend") if (!hasorgans(target)) return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0) if(I.robotic >= 2) user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \ "\blue You repair [target]'s [I.name] with [tool]." ) I.damage = 0 + return 1 + else if(current_type == "insert") + var/obj/item/organ/internal/I = target.get_int_organ(surgery.current_organ) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/off_tool = user.get_inactive_hand() + I = off_tool + user.drop_item() + I.insert(target) + user.visible_message("\blue [user] has reattached [target]'s [I] with \the [tool]." , \ + "\blue You have reattached [target]'s [I] with \the [tool].") + if(I && istype(I)) + I.status &= ~ORGAN_CUT_AWAY + else if (current_type == "install") + user.visible_message("\blue [user] has installed \the [tool] into [target]'s [affected.name].", \ + "\blue You have installed \the [tool] into [target]'s [affected.name].") + + var/obj/item/device/mmi/M = tool + var/obj/item/organ/internal/brain/mmi_holder/holder = new() + if (istype(M, /obj/item/device/mmi/posibrain)) + holder.robotize() + + holder.insert(target) + user.unEquip(tool) + tool.forceMove(holder) + holder.stored_mmi = tool + holder.update_from_mmi() + + if(M.brainmob && M.brainmob.mind) + M.brainmob.mind.transfer_to(target) + + else if(current_type == "extract") + if(I && I.owner == target) + user.visible_message("\blue [user] has decoupled [target]'s [surgery.current_organ] with \the [tool]." , \ + "\blue You have decoupled [target]'s [surgery.current_organ] with \the [tool].") + + add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") + spread_germs_to_organ(I, user) + I.status |= ORGAN_CUT_AWAY + 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 + +/datum/surgery_step/robotics/manipulate_robotic_organs/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + + if(current_type == "mend") if (!hasorgans(target)) return var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -282,108 +425,21 @@ if(I) I.take_damage(rand(3,5),0) -/datum/surgery_step/robotics/detatch_organ_robotic - - allowed_tools = list( - /obj/item/device/multitool = 100 - ) - - min_duration = 90 - max_duration = 110 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && (affected.status & ORGAN_ROBOT))) - return 0 - if(!affected.open_enough_for_surgery()) - return 0 - - surgery.current_organ = null - surgery.organ_ref = null - - var/list/attached_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/internal/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 - - surgery.current_organ = organ_to_remove - surgery.organ_ref = attached_organs[organ_to_remove] - - return ..() && organ_to_remove - - begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] starts to decouple [target]'s [surgery.current_organ] with \the [tool].", \ - "You start to decouple [target]'s [surgery.current_organ] with \the [tool]." ) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("\blue [user] has decoupled [target]'s [surgery.current_organ] with \the [tool]." , \ - "\blue You have decoupled [target]'s [surgery.current_organ] with \the [tool].") - - var/obj/item/organ/internal/I = target.get_int_organ(surgery.current_organ) - if(I && istype(I)) - I.status |= ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + else if(current_type == "insert") user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ "\red Your hand slips, disconnecting \the [tool].") -/datum/surgery_step/robotics/attach_organ_robotic - allowed_tools = list( - /obj/item/weapon/screwdriver = 100, - ) - - min_duration = 100 - max_duration = 120 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && (affected.status & ORGAN_ROBOT))) - return 0 - if(!affected.open_enough_for_surgery()) - return 0 - - surgery.current_organ = null - surgery.organ_ref = null - - var/list/removable_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/internal/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 - - surgery.current_organ = organ_to_replace - surgery.organ_ref = removable_organs[organ_to_replace] - return ..() - - begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] begins reattaching [target]'s [surgery.current_organ] with \the [tool].", \ - "You start reattaching [target]'s [surgery.current_organ] with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("\blue [user] has reattached [target]'s [surgery.current_organ] with \the [tool]." , \ - "\blue You have reattached [target]'s [surgery.current_organ] with \the [tool].") - - var/obj/item/organ/internal/I = target.get_int_organ(surgery.current_organ) - if(I && istype(I)) - I.status &= ~ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + else if(current_type == "extract") user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ "\red Your hand slips, disconnecting \the [tool].") + else if (current_type == "install") + user.visible_message("\red [user]'s hand slips!.", \ + "\red Your hand slips!") + return -1 + + + /datum/surgery_step/robotics/install_mmi allowed_tools = list( /obj/item/device/mmi = 100 diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index f1cb16f138c..2c9570dab9b 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -3,11 +3,13 @@ var/name = "surgery" var/status = 1 var/list/steps = list() + /* var/eyes = 0 var/face = 0 var/appendix = 0 var/ribcage = 0 var/head_reattach = 0 //Steps in a surgery + */ var/can_cancel = 1 var/step_in_progress = 0 @@ -17,7 +19,7 @@ var/list/possible_locs = list() //Multiple locations -- c0 var/obj/item/organ/organ_ref //Operable body part var/current_organ = "organ" - var/list/allowed_species = null + var/list/allowed_species = list(/mob/living/carbon/human) var/list/disallowed_species = null /datum/surgery/proc/can_start(mob/user, mob/living/carbon/target) @@ -31,7 +33,7 @@ var/datum/surgery_step/S = get_surgery_step() if(S) - if(S.begin_step(user, target, user.zone_sel.selecting, user.get_active_hand(), src)) + if(S.try_op(user, target, user.zone_sel.selecting, user.get_active_hand(), src)) return 1 return 0 @@ -51,13 +53,15 @@ // type path referencing tools that can be used for this step, and how well are they suited for it var/list/allowed_tools = null - // type paths referencing mutantraces that this step applies to. + var/implement_type = null // duration of the step var/min_duration = 0 var/max_duration = 0 var/name + var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. + var/accept_any_item = 0 // evil infection stuff that will make everyone hate me var/can_infect = 0 @@ -67,15 +71,42 @@ var/list/allowed_species = null var/list/disallowed_species = null +/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/success = 0 + if(accept_hand) + if(!tool) + success = 1 + if(accept_any_item) + if(tool && tool_quality(tool)) + success = 1 + else + for(var/path in allowed_tools) + if(istype(tool, path)) + implement_type = path + if(tool_quality(tool)) + success = 1 + + if(success) + if(target_zone == surgery.location) + initiate(user, target, target_zone, tool, surgery) + return 1//returns 1 so we don't stab the guy in the dick or wherever. + if(isrobot(user) && user.a_intent != I_HARM) //to save asimov borgs a LOT of heartache + return 1 + return 0 + /datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) surgery.step_in_progress = 1 + if(begin_step(user, target, target_zone, tool, surgery) == -1) + surgery.step_in_progress = 0 + return + if(do_after(user, max_duration, target = target)) var/advance = 0 var/prob_chance = 100 - if(tool) //this means it isn't a require nd or any item step. - prob_chance = allowed_tools[tool] + if(implement_type) //this means it isn't a require nd or any item step. + prob_chance = allowed_tools[implement_type] prob_chance *= get_location_modifier(target) if(prob(prob_chance) || isrobot(user)) @@ -176,7 +207,7 @@ S.fail_step(user, M, zone, tool) //malpractice~ else // This failing silently was a pain. user << "You must remain close to your patient to conduct surgery." - surgery.step_in_progress -= zone // Clear the in-progress flag. + surgery.step_in_progress = 0 // Clear the in-progress flag. return 1 //don't want to do weapony things after surgery if (user.a_intent == I_HELP)