From 7d2983b4bf2138ae88d68a2de4a59d878cd82093 Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Sun, 14 Aug 2016 18:12:23 -0700 Subject: [PATCH] Makes IPC surgery much more reliable, object insertion surgery works better now, and `can_use` is actually called now. --- code/_onclick/item_attack.dm | 10 +- .../gamemodes/changeling/powers/revive.dm | 1 - code/modules/mob/living/carbon/brain/MMI.dm | 24 +- .../mob/living/carbon/brain/brain_item.dm | 6 +- .../mob/living/carbon/carbon_defenses.dm | 7 + code/modules/mob/living/carbon/human/death.dm | 8 +- .../living/carbon/human/human_attackhand.dm | 11 +- code/modules/mob/living/carbon/human/life.dm | 3 +- code/modules/surgery/bones.dm | 46 ++- code/modules/surgery/encased.dm | 5 +- code/modules/surgery/face.dm | 35 +-- code/modules/surgery/generic.dm | 15 +- code/modules/surgery/helpers.dm | 31 +- code/modules/surgery/implant.dm | 110 ++++--- code/modules/surgery/limb_reattach.dm | 143 ++++++--- code/modules/surgery/organs/augments_eyes.dm | 6 +- .../surgery/organs/augments_internal.dm | 2 +- code/modules/surgery/organs/body_egg.dm | 4 +- code/modules/surgery/organs/organ.dm | 1 + code/modules/surgery/organs/organ_external.dm | 63 ++-- code/modules/surgery/organs/organ_icon.dm | 2 +- code/modules/surgery/organs/organ_internal.dm | 32 +- code/modules/surgery/organs/organ_stump.dm | 2 +- code/modules/surgery/organs/parasites.dm | 3 +- code/modules/surgery/organs/subtypes/grey.dm | 2 +- .../surgery/organs/subtypes/machine.dm | 47 +-- code/modules/surgery/organs/subtypes/misc.dm | 1 + .../surgery/organs/subtypes/standard.dm | 6 +- code/modules/surgery/organs/subtypes/xenos.dm | 8 +- code/modules/surgery/organs_internal.dm | 23 +- code/modules/surgery/other.dm | 81 +++-- code/modules/surgery/robotics.dm | 279 +++++++----------- code/modules/surgery/surgery.dm | 8 +- 33 files changed, 564 insertions(+), 461 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 3516c02a2ae..1fa83b66513 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -33,11 +33,19 @@ var/messagesource = M if(can_operate(M)) //Checks if mob is lying down on table for surgery - if(istype(src,/obj/item/robot_parts))//popup ovveride for direct attach + if(istype(src,/obj/item/robot_parts))//popup override for direct attach if(!attempt_initiate_surgery(src, M, user,1)) return 0 else return 1 + if(istype(src,/obj/item/organ/external)) + var/obj/item/organ/external/E = src + if(E.robotic == 2) // Robot limbs are less messy to attach + if(!attempt_initiate_surgery(src, M, user,1)) + return 0 + else + return 1 + if(istype(src,/obj/item/weapon/screwdriver) && M.get_species() == "Machine") if(!attempt_initiate_surgery(src, M, user)) return 0 diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 1bb19749ac1..b6692817650 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -51,7 +51,6 @@ O.number_wounds = 0 O.open = 0 O.perma_injury = 0 - O.stage = 0 O.status = 0 O.trace_chemicals = list() O.wounds = list() diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index ec0791d9e09..545be2f8613 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -178,4 +178,26 @@ /obj/item/device/mmi/syndie name = "Syndicate Man-Machine Interface" desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores." - syndiemmi = 1 \ No newline at end of file + syndiemmi = 1 + +/obj/item/device/mmi/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H) + if(!brainmob) + return 0 + if(!parent) + log_debug("Attempting to insert into a null parent!") + return 0 + if(H.get_int_organ(/obj/item/organ/internal/brain)) + // one brain at a time + return 0 + var/obj/item/organ/internal/brain/mmi_holder/holder = new() + holder.parent_organ = parent.limb_name + forceMove(holder) + holder.stored_mmi = src + holder.update_from_mmi() + if(istype(src, /obj/item/device/mmi/posibrain)) + holder.robotize() + if(brainmob && brainmob.mind) + brainmob.mind.transfer_to(H) + holder.insert(H) + + return 1 diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index dd2e81ed35b..26d25238197 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -79,7 +79,7 @@ if(istype(owner,/mob/living/carbon/human)) var/mob/living/carbon/human/H = owner H.update_hair(1) - ..() + . = ..() /obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0) @@ -100,7 +100,9 @@ brainmob.mind.transfer_to(target) else target.key = brainmob.key - ..(target, special = special, dont_remove_slot = brain_already_exists) + else + log_debug("Multibrain shenanigans at ([target.x],[target.y],[target.z]), mob '[target]'") + ..(target, special = special) /obj/item/organ/internal/brain/prepare_eat() return // Too important to eat. diff --git a/code/modules/mob/living/carbon/carbon_defenses.dm b/code/modules/mob/living/carbon/carbon_defenses.dm index efebc58ffc1..69f882379ed 100644 --- a/code/modules/mob/living/carbon/carbon_defenses.dm +++ b/code/modules/mob/living/carbon/carbon_defenses.dm @@ -36,4 +36,11 @@ for(var/datum/disease/D in user.viruses) if(D.IsSpreadByTouch()) ContractDisease(D) + + if(lying) + if(surgeries.len) + if(user != src && user.a_intent == "help") + for(var/datum/surgery/S in surgeries) + if(S.next_step(user, src)) + return 1 return 0 diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index d3606b12b8a..e4427f6d74a 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -12,13 +12,15 @@ animation.master = src playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1) + else + playsound(src.loc, 'sound/goonstation/effects/robogib.ogg', 50, 1) for(var/obj/item/organ/internal/I in internal_organs) if(isturf(loc)) - I.remove(src) - I.forceMove(get_turf(src)) + var/atom/movable/thing = I.remove(src) + thing.forceMove(get_turf(src)) spawn() - I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5) + thing.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5) for(var/obj/item/organ/external/E in src.organs) if(istype(E, /obj/item/organ/external/chest)) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 2ca74f02c86..e382768722f 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -13,7 +13,7 @@ if(H.hand) temp = H.organs_by_name["l_hand"] if(!temp || !temp.is_usable()) - to_chat(H, "\red You can't use your hand.") + to_chat(H, "You can't use your hand.") return ..() @@ -62,10 +62,9 @@ for(var/datum/surgery/S in src.surgeries) if(S.next_step(M, src)) return 1 - else - help_shake_act(M) - add_logs(src, M, "shaked") - return 1 + help_shake_act(M) + add_logs(src, M, "shaked") + return 1 if(health >= config.health_threshold_crit) help_shake_act(M) add_logs(src, M, "shaked") @@ -231,4 +230,4 @@ return /mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d557fb65fed..6e74c90f08c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1113,7 +1113,8 @@ return if(H.species && H.species.flags & NO_BREATHE) return //no puking if you can't smell! - if(H.mind.assigned_role == "Detective") + // Humans can lack a mind datum, y'know + if(H.mind && H.mind.assigned_role == "Detective") return //too cool for puke to_chat(H, "You smell something foul...") H.fakevomit() diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index a32186f2827..fc7f631c10e 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -4,12 +4,12 @@ ////////////////////////////////////////////////////////////////// ///Surgery Datums /datum/surgery/bone_repair - name = "bone repair" + name = "Bone Repair" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize) possible_locs = list("chest", "l_arm", "l_hand", "r_arm", "r_hand","r_leg", "r_foot", "l_leg", "l_foot", "groin") /datum/surgery/bone_repair/skull - name = "bone repair" + name = "Skull Repair" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/mend_skull, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize) possible_locs = list("head") @@ -17,14 +17,14 @@ if(istype(target,/mob/living/carbon/human)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(affected && (affected.status & ORGAN_ROBOT)) + if(!affected) return 0 - if(affected && (affected.status & ORGAN_BROKEN)) + if(affected.status & ORGAN_ROBOT) + return 0 + if(affected.cannot_break) + return 0 + if(affected.status & ORGAN_BROKEN) return 1 - if(target.get_species() == "Machine") - return 0 - if(target.get_species() == "Diona") - return 0 return 1 @@ -43,13 +43,12 @@ /datum/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break) && affected.open == 2 && affected.stage == 0 + return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break) /datum/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(affected.stage == 0) - user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ - "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") + user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ + "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) ..() @@ -57,7 +56,6 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message(" [user] applies some [tool] to [target]'s bone in [affected.name]", \ " You apply some [tool] to [target]'s bone in [affected.name] with \the [tool].") - affected.stage = 1 return 1 @@ -79,7 +77,7 @@ /datum/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name != "head" && affected.open == 2 && affected.stage == 1 + return affected && !(affected.status & ORGAN_ROBOT) /datum/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -93,7 +91,6 @@ if(affected.status & ORGAN_BROKEN) user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ " You set the bone in [target]'s [affected.name] in place with \the [tool].") - affected.stage = 2 return 1 else user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ @@ -119,7 +116,7 @@ /datum/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" && affected.open == 2 && affected.stage == 1 + return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" /datum/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \ @@ -128,16 +125,15 @@ /datum/surgery_step/mend_skull/end_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) - user.visible_message(" [user] sets [target]'s skull with \the [tool]." , \ - " You set [target]'s skull with \the [tool].") - affected.stage = 2 + user.visible_message(" [user] sets [target]'s [affected.encased] with \the [tool]." , \ + " You set [target]'s [affected.encased] with \the [tool].") return 1 /datum/surgery_step/mend_skull/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) - user.visible_message(" [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \ - " Your hand slips, damaging [target]'s face with \the [tool]!") + user.visible_message("[user]'s hand slips, damaging [target]'s face with \the [tool]!" , \ + "Your hand slips, damaging [target]'s face with \the [tool]!") var/obj/item/organ/external/head/h = affected h.createwound(BRUISE, 10) h.disfigured = 1 @@ -157,7 +153,7 @@ /datum/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.open == 2 && affected.stage == 2 + return affected && !(affected.status & ORGAN_ROBOT) /datum/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -165,14 +161,14 @@ "You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].") ..() -/datum/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/finish_bone/end_step(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) user.visible_message(" [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ " You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) affected.status &= ~ORGAN_BROKEN affected.status &= ~ORGAN_SPLINTED - affected.stage = 0 affected.perma_injury = 0 + surgery.can_cancel = 1 return 1 @@ -180,4 +176,4 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message(" [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ " Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index 90460f34c21..a1ea245d138 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -52,6 +52,8 @@ user.visible_message(" [user] has cut [target]'s [affected.encased] open with \the [tool].", \ " You have cut [target]'s [affected.encased] open with \the [tool].") affected.open = 2.5 + // crossin' the rubicon + surgery.can_cancel = 0 return 1 /datum/surgery_step/open_encased/saw/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -223,5 +225,6 @@ user.visible_message(msg, self_msg) affected.open = 2 + surgery.can_cancel = 1 - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 6e947511dd6..406c1f83083 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -3,7 +3,7 @@ // FACE SURGERY // ////////////////////////////////////////////////////////////////// /datum/surgery/plastic_surgery - name = "face repair" + name = "Face Repair" steps = list(/datum/surgery_step/generic/cut_face, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/face/mend_vocal, /datum/surgery_step/face/fix_face,/datum/surgery_step/face/cauterize) possible_locs = list("head") @@ -13,9 +13,11 @@ if(istype(target,/mob/living/carbon/human)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(affected && (affected.status & ORGAN_ROBOT)) + if(!affected) return 0 - if((target.get_species() == "Machine")) + if(affected.status & ORGAN_ROBOT) + return 0 + if(!affected.disfigured) return 0 return 1 @@ -23,14 +25,6 @@ priority = 2 can_infect = 0 -/datum/surgery_step/face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected || (affected.status & ORGAN_ROBOT)) - return 0 - return target_zone == "mouth" - /datum/surgery_step/generic/cut_face name = "make incision" allowed_tools = list( @@ -45,9 +39,6 @@ time = 16 -/datum/surgery_step/generic/cut_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - return ..() && target_zone == "mouth" //&& target.op_stage.face == 0//I NEED TO REPLACE THE OPSTAGE SHIT! - /datum/surgery_step/generic/cut_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \ "You start to cut open [target]'s face and neck with \the [tool].") @@ -56,7 +47,6 @@ /datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message(" [user] has cut open [target]'s face and neck with \the [tool]." , \ " You have cut open [target]'s face and neck with \the [tool].",) - //target.op_stage.face = 1//DID I MENTION I NEED TO REPLACE THE OPSTAGE SHIT! return 1 @@ -80,9 +70,6 @@ time = 24 -/datum/surgery_step/face/mend_vocal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - return ..()// && target.op_stage.face == 1 //NO REALLY NED TO REPLACE, MAYBE WITH FUCKING istype(S.get_surgery_step(), /datum/surgery_step/cut_face)) OR SOMETHING - /datum/surgery_step/face/mend_vocal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \ "You start mending [target]'s vocal cords with \the [tool].") @@ -91,7 +78,6 @@ /datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message(" [user] mends [target]'s vocal cords with \the [tool].", \ " You mend [target]'s vocal cords with \the [tool].") - //target.op_stage.face = 2//I NEED TO REPLACE THE OPSTAGE SHIT! return 1 /datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -110,9 +96,6 @@ time = 64 -/datum/surgery_step/face/fix_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - return ..() //&& target.op_stage.face == 2//I NEED TO REPLACE THE OPSTAGE SHIT! - /datum/surgery_step/face/fix_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \ "You start pulling skin on [target]'s face back in place with \the [tool].") @@ -121,7 +104,6 @@ /datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message(" [user] pulls skin on [target]'s face back in place with \the [tool].", \ " You pull skin on [target]'s face back in place with \the [tool].") - //target.op_stage.face = 3//I NEED TO REPLACE THE OPSTAGE SHIT! return 1 /datum/surgery_step/face/fix_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -145,9 +127,6 @@ time = 24 -/datum/surgery_step/face/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - return ..()// && target.op_stage.face > 0//I NEED TO REPLACE THE OPSTAGE SHIT! - /datum/surgery_step/face/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \ "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].") @@ -159,12 +138,10 @@ " You cauterize the incision on [target]'s face and neck with \the [tool].") affected.open = 0 affected.status &= ~ORGAN_BLEEDING - //if(target.op_stage.face == 3)//I NEED TO REPLACE THE OPSTAGE SHIT! var/obj/item/organ/external/head/h = affected h.disfigured = 0 h.update_icon() target.regenerate_icons() - //target.op_stage.face = 0//I NEED TO REPLACE THE OPSTAGE SHIT! return 1 @@ -174,4 +151,4 @@ " Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") target.apply_damage(4, BURN, affected) - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index d02787eb3b5..1441cb83e8b 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -83,11 +83,6 @@ time = 24 -/datum/surgery_step/generic/clamp_bleeders/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) - return ..() && affected.open && (affected.status & ORGAN_BLEEDING) - - /datum/surgery_step/generic/clamp_bleeders/begin_step(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) user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \ @@ -122,10 +117,6 @@ time = 24 -/datum/surgery_step/generic/retract_skin/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) - return ..() && affected.open == 1 && !(affected.status & ORGAN_BLEEDING) - /datum/surgery_step/generic/retract_skin/begin_step(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) var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." @@ -264,7 +255,9 @@ add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it - affected.droplimb(1,DROPLIMB_EDGE) + var/atom/movable/thing = affected.droplimb(1,DROPLIMB_EDGE) + if(istype(thing,/obj/item)) + user.put_in_hands(thing) return 1 /datum/surgery_step/generic/amputate/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -273,4 +266,4 @@ " Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") affected.createwound(CUT, 30) affected.fracture() - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index a21a7422696..1991ce8ec21 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -28,19 +28,26 @@ for(var/path in S.allowed_mob) if(istype(M, path)) + // If there are multiple surgeries with the same name, + // prepare to cry available_surgeries[S.name] = S break if(override) + var/datum/surgery/S if(istype(I,/obj/item/robot_parts)) - var/datum/surgery/S = available_surgeries["robotic limb attachment"] - if(S) - var/datum/surgery/procedure = new S.type - if(procedure) - procedure.location = selected_zone - M.surgeries += procedure - procedure.organ_ref = affecting - procedure.next_step(user, M) + S = available_surgeries["Apply Robotic Prosthetic"] + if(istype(I,/obj/item/organ/external)) + var/obj/item/organ/external/E = I + if(E.robotic == 2) + S = available_surgeries["Synthetic Limb Reattachment"] + if(S) + var/datum/surgery/procedure = new S.type + if(procedure) + procedure.location = selected_zone + M.surgeries += procedure + procedure.organ_ref = affecting + procedure.next_step(user, M) else var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries @@ -77,7 +84,7 @@ -proc/get_location_modifier(mob/M) +/proc/get_location_modifier(mob/M) var/turf/T = get_turf(M) if(locate(/obj/machinery/optable, T)) return 1 @@ -86,4 +93,8 @@ proc/get_location_modifier(mob/M) else if(locate(/obj/structure/stool/bed, T)) return 0.7 else - return 0.5 \ No newline at end of file + return 0.5 + +// Called when a limb containing this object is placed back on a body +/atom/movable/proc/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H) + return 0 diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 1aec72f1d63..a3b7ec2d908 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -6,41 +6,45 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/cavity_implant - name = "cavity implant/removal" + name = "Cavity Implant/Removal" steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw, /datum/surgery_step/open_encased/retract, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/open_encased/close,/datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) - + can_cancel = 0 possible_locs = list("chest","head") /datum/surgery/cavity_implant/soft - name = "cavity implant/removal" + name = "Cavity Implant/Removal" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/generic/cut_open, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize) possible_locs = list("groin") /datum/surgery/cavity_implant/synth - name = "robotic cavity implant" + name = "Robotic Cavity Implant/Removal" steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/place_item,/datum/surgery_step/robotics/external/close_hatch) possible_locs = list("chest","head","groin") -/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/target) - if(target.get_species() == "Machine") +/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_ROBOT) return 0 return 1 -/datum/surgery/cavity_implant/synth/can_start(mob/user, mob/living/carbon/target) - return target.get_species() == "Machine" +/datum/surgery/cavity_implant/synth/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + return (affected.status & ORGAN_ROBOT) /datum/surgery_step/cavity priority = 1 -/datum/surgery_step/cavity/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) - /datum/surgery_step/cavity/proc/get_max_wclass(obj/item/organ/external/affected) switch(affected.limb_name) if("head") @@ -77,16 +81,11 @@ time = 54 -/datum/surgery_step/cavity/make_space/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) - return ..() && !affected.cavity && !affected.hidden - /datum/surgery_step/cavity/make_space/begin_step(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) user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) - affected.cavity = 1 ..() /datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -111,16 +110,11 @@ time = 24 -/datum/surgery_step/cavity/close_space/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) - return ..() && affected.cavity - /datum/surgery_step/cavity/close_space/begin_step(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) user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \ "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) - affected.cavity = 0 ..() /datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -145,17 +139,24 @@ if(!ishuman(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/can_fit = affected && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) - return ..() && can_fit + if(!affected) + to_chat(user, "\The [target] lacks a [parse_zone(target_zone)]!") + return 0 + if(tool) + var/can_fit = !affected.hidden && tool.w_class <= get_max_wclass(affected) + if(!can_fit) + to_chat(user, "\The [tool] won't fit in \The [affected.name]!") + return 0 + return ..() /datum/surgery_step/cavity/place_item/begin_step(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) - for(var/obj/item/I in target.internal_organs) + for(var/obj/item/I in affected.contents) if(!istype(I, /obj/item/organ)) IC = I break if(istype(tool,/obj/item/weapon/cautery)) - to_chat(user, "you prepare to close the cavity wall.") + to_chat(user, "You prepare to close the cavity wall.") else if(tool) user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ "You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) @@ -203,8 +204,7 @@ affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1) user.drop_item() target.internal_organs += tool - tool.loc = target - affected.cavity = 0 + tool.forceMove(affected) return 1 else if(IC) @@ -222,22 +222,35 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/cavity_implant_rem - name = "implant removal" + name = "Implant Removal" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize/) possible_locs = list("chest")//head is for borers..i can put it elsewhere /datum/surgery/cavity_implant_rem/synth - name = "implant removal" + name = "Implant Removal" steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/robotics/external/close_hatch) possible_locs = list("chest")//head is for borers..i can put it elsewhere -/datum/surgery/cavity_implant_rem/can_start(mob/user, mob/living/carbon/target) - if(target.get_species() == "Machine") +/datum/surgery/cavity_implant_rem/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_ROBOT) return 0 return 1 -/datum/surgery/cavity_implant_rem/synth/can_start(mob/user, mob/living/carbon/target) - return target.get_species() == "Machine" +/datum/surgery/cavity_implant_rem/synth/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(!(affected.status & ORGAN_ROBOT)) + return 0 + + return 1 /datum/surgery_step/cavity/implant_removal name = "extract implant" @@ -309,25 +322,34 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/embedded_removal - name = "removal of embedded objects" + name = "Removal of Embedded Objects" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/remove_object, /datum/surgery_step/generic/cauterize) possible_locs = list("r_arm","l_arm","r_leg","l_leg","r_hand","r_foot","l_hand","l_foot","groin","chest","head") /datum/surgery/embedded_removal/synth - name = "removal of embedded objects" steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch, /datum/surgery_step/remove_object, /datum/surgery_step/robotics/external/close_hatch) possible_locs = list("r_arm","l_arm","r_leg","l_leg","r_hand","r_foot","l_hand","l_foot","groin","chest","head") -/datum/surgery/embedded_removal/can_start(mob/user, mob/living/carbon/target) - if(target.get_species() == "Machine") +/datum/surgery/embedded_removal/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_ROBOT) return 0 return 1 -/datum/surgery/embedded_removal/synth/can_start(mob/user, mob/living/carbon/target) - if(target.get_species() == "Machine") - return 1 - return 0 +/datum/surgery/embedded_removal/synth/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(!(affected.status & ORGAN_ROBOT)) + return 0 + return 1 /datum/surgery_step/remove_object name = "remove embedded objects" diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index ad0a1973b8f..873506338a7 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -4,7 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/amputation - name = "amputation" + name = "Amputation" steps = list(/datum/surgery_step/generic/amputate) possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") @@ -13,16 +13,18 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if((target.get_species() == "Machine")) - return 0 if(!affected) return 0 + if(affected.status & ORGAN_ROBOT) + return 0 + if(affected.cannot_amputate) + return 0 return 1 /datum/surgery/reattach - name = "limb attachment" + name = "Limb Reattachment" steps = list(/datum/surgery_step/limb/attach,/datum/surgery_step/limb/connect) possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") @@ -30,29 +32,30 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(target.get_species() == "Machine") + // RIP bi-centennial man + return 0 if(!affected) return 1 - if((target.get_species() == "Machine")) - return 0 - return 0 + return 0 /datum/surgery/reattach_synth - name = "limb attachment" - steps = list(/datum/surgery_step/limb/attach) + name = "Synthetic Limb Reattachment" + steps = list(/datum/surgery_step/limb/attach/robo) possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") /datum/surgery/reattach_synth/can_start(mob/user, mob/living/carbon/target) if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(!affected && (target.get_species() == "Machine")) + if(!affected) return 1 return 0 /datum/surgery/robo_attach - name = "robotic limb attachment" + name = "Apply Robotic Prosthetic" steps = list(/datum/surgery_step/limb/mechanize) possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") @@ -67,14 +70,14 @@ /datum/surgery_step/limb/ can_infect = 0 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(affected) - return 0 - var/list/organ_data = target.species.has_limbs["[target_zone]"] - return !isnull(organ_data) +/datum/surgery_step/limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected) + return 0 + var/list/organ_data = target.species.has_limbs["[target_zone]"] + return !isnull(organ_data) /datum/surgery_step/limb/attach name = "attach limb" @@ -82,6 +85,31 @@ time = 32 +/datum/surgery_step/limb/attach/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(!..()) + return 0 + if(!istype(tool, /obj/item/organ/external)) + return 0 + var/obj/item/organ/external/E = tool + if(target.get_organ(E.limb_name)) + // This catches attaching an arm to a missing hand while the arm is still there + to_chat(user, "[target] already has an [E.name]!") + return 0 + if(E.limb_name != target_zone) + // This ensures you must be aiming at the appropriate location to attach + // this limb. (Can't aim at a missing foot to re-attach a missing arm) + to_chat(user, "The [E.name] does not go there.") + return 0 + // if(E.parent_organ && !target.get_organ(E.parent_organ)) + // // No rayman allowed + // return 0 + if(!is_correct_limb(E)) + to_chat(user, "This is not the correct limb type for this surgery!") + return 0 + + return 1 + + /datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = tool user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ @@ -91,29 +119,7 @@ var/obj/item/organ/external/E = tool user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].", \ "You have attached [target]'s [E.name] to the [E.amputation_point].") - user.unEquip(E) - E.replaced(target) - E.forceMove(target) - if(target.get_species() == "Machine")//as this is the only step needed for ipc put togethers - if(!(E.dna) && E.robotic == 2 && target.dna) - E.dna = target.dna.Clone() - if(!E.blood_DNA) - E.blood_DNA = list() - E.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type - if(target_zone == "head") - var/obj/item/organ/external/head/H = target.get_organ("head") - var/datum/robolimb/robohead = all_robolimbs[H.model] - if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe. - H.h_style = "" - H.f_style = "" - target.m_style = "" - E.status &= ~ORGAN_DESTROYED - if(E.children) - for(var/obj/item/organ/external/C in E.children) - C.status &= ~ORGAN_DESTROYED - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() + attach_limb(user, target, E) return 1 /datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -123,6 +129,48 @@ target.apply_damage(10, BRUTE, null, sharp=1) return 0 + +/datum/surgery_step/limb/attach/proc/is_correct_limb(obj/item/organ/external/E) + if(E.status & ORGAN_ROBOT) + return 0 + return 1 + +/datum/surgery_step/limb/attach/proc/attach_limb(mob/living/user, mob/living/carbon/human/target, obj/item/organ/external/E) + user.unEquip(E) + E.replaced(target) + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + +// This is a step that handles robotic limb attachment while skipping the "connect" step +// THIS IS DISTINCT FROM USING A CYBORG LIMB TO CREATE A NEW LIMB ORGAN +/datum/surgery_step/limb/attach/robo + name = "attach robotic limb" + +/datum/surgery_step/limb/attach/robo/is_correct_limb(obj/item/organ/external/E) + if(!(E.status & ORGAN_ROBOT)) + return 0 + return 1 + +/datum/surgery_step/limb/attach/robo/attach_limb(mob/living/user, mob/living/carbon/human/target, obj/item/organ/external/E) + // Fixes fabricator IPC heads + if(!(E.dna) && E.robotic == 2 && target.dna) + E.set_dna(target.dna) + if(E.limb_name == "head") + var/obj/item/organ/external/head/H = target.get_organ("head") + var/datum/robolimb/robohead = all_robolimbs[H.model] + if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe. + H.h_style = "" + H.f_style = "" + target.m_style = "" + ..() + E.status &= ~ORGAN_DESTROYED + if(E.children) + for(var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DESTROYED + + /datum/surgery_step/limb/connect name = "connect limb" allowed_tools = list( @@ -134,9 +182,11 @@ time = 32 + /datum/surgery_step/limb/connect/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - return E && !E.is_stump() && (E.status & ORGAN_DESTROYED) + if(!hasorgans(target)) + return 0 + return 1 /datum/surgery_step/limb/connect/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = target.get_organ(target_zone) @@ -167,7 +217,7 @@ return 0 /datum/surgery_step/limb/mechanize - name = "attach robotic limb" + name = "apply robotic prosthetic" allowed_tools = list(/obj/item/robot_parts = 100) time = 32 @@ -177,6 +227,7 @@ var/obj/item/robot_parts/p = tool if(p.part) if(!(target_zone in p.part)) + to_chat(user, "\The [tool] does not go there!") return 0 return isnull(target.get_organ(target_zone)) @@ -196,13 +247,13 @@ var/list/organ_data = target.species.has_limbs["[part_name]"] if(!organ_data) continue + // This will break if there's more than one stump ever var/obj/item/organ/external/stump = target.organs_by_name["limb stump"] if(stump) stump.remove(target) var/new_limb_type = organ_data["path"] var/obj/item/organ/external/new_limb = new new_limb_type(target) new_limb.robotize(L.model_info) - new_limb.replaced(target) new_limb.status &= ~ORGAN_DESTROYED if(new_limb.children) for(var/obj/item/organ/external/C in new_limb.children) diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 679a98c98f4..78878917d6d 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -40,7 +40,7 @@ M.sight |= vision_flags /obj/item/organ/internal/cyberimp/eyes/remove(var/mob/living/carbon/M, var/special = 0) - ..() + . = ..() M.sight ^= vision_flags if(istype(owner,/mob/living/carbon/human) && eye_colour) var/mob/living/carbon/human/HMN = owner @@ -97,7 +97,7 @@ M.permanent_huds |= H /obj/item/organ/internal/cyberimp/eyes/hud/remove(var/mob/living/carbon/M, var/special = 0) - ..() + . = ..() if(HUD_type) var/datum/atom_hud/H = huds[HUD_type] M.permanent_huds ^= H @@ -132,4 +132,4 @@ // Welding with thermals will still hurt your eyes a bit. /obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity) - return \ No newline at end of file + return diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 2fa12d1a0dc..b860e3f062c 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -116,7 +116,7 @@ r_hand_obj.flags ^= NODROP /obj/item/organ/internal/cyberimp/brain/anti_drop/remove(var/mob/living/carbon/M, special = 0) - ..() + . = ..() if(active) ui_action_click() diff --git a/code/modules/surgery/organs/body_egg.dm b/code/modules/surgery/organs/body_egg.dm index 3653e3df327..335d4e5b751 100644 --- a/code/modules/surgery/organs/body_egg.dm +++ b/code/modules/surgery/organs/body_egg.dm @@ -25,7 +25,7 @@ owner.med_hud_set_status() spawn(0) RemoveInfectionImages(owner) - ..() + . = ..() /obj/item/organ/internal/body_egg/process() if(!owner) @@ -46,4 +46,4 @@ return /obj/item/organ/internal/body_egg/proc/RemoveInfectionImages() - return \ No newline at end of file + return diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index b49ccc6a838..26d50abaa75 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -314,6 +314,7 @@ var/list/organ_cache = list() msg_admin_attack("[key_name_admin(user)] removed a vital organ ([src]) from [key_name_admin(owner)]") owner.death() owner = null + return src /obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 8ec993c8db8..e2702b36afe 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -51,8 +51,6 @@ var/broken_description var/open = 0 - var/stage = 0 - var/cavity = 0 var/sabotaged = 0 //If a prosthetic limb is emagged, it will detonate when it fails. var/encased // Needs to be opened with a saw to access the organs. @@ -71,6 +69,9 @@ if(parent && parent.children) parent.children -= src + if(owner) + owner.organs_by_name[limb_name] = null + if(internal_organs) for(var/obj/item/organ/internal/O in internal_organs) internal_organs -= O @@ -87,38 +88,35 @@ return ..() /obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob) - switch(stage) + switch(open) if(0) if(istype(W,/obj/item/weapon/scalpel)) spread_germs_to_organ(src,user) - user.visible_message("[user] cuts [src] open with [W]!") - stage++ + user.visible_message("[user] cuts [src] open with [W]!") + open++ return if(1) if(istype(W,/obj/item/weapon/retractor)) spread_germs_to_organ(src,user) - user.visible_message("[user] cracks [src] open like an egg with [W]!") - stage++ + user.visible_message("[user] cracks [src] open like an egg with [W]!") + open++ return if(2) if(istype(W,/obj/item/weapon/hemostat)) spread_germs_to_organ(src,user) if(contents.len) var/obj/item/removing = pick(contents) - removing.loc = get_turf(user.loc) var/obj/item/organ/internal/O = removing if(istype(O)) O.status |= ORGAN_CUT_AWAY if(!O.sterile) spread_germs_to_organ(O,user) // This wouldn't be any cleaner than the actual surgery - O.forceMove(get_turf(src)) - if(!(user.l_hand && user.r_hand)) - user.put_in_hands(removing) - user.visible_message("[user] extracts [removing] from [src] with [W]!") + user.put_in_hands(removing) + user.visible_message("[user] extracts [removing] from [src] with [W]!") else - user.visible_message("[user] fishes around fruitlessly in [src] with [W].") + user.visible_message("[user] fishes around fruitlessly in [src] with [W].") return - ..() + . = ..() /obj/item/organ/external/update_health() @@ -139,14 +137,12 @@ status = status & ~ORGAN_DESTROYED forceMove(owner) if(istype(owner)) + if(!isnull(owner.organs_by_name[limb_name])) + log_debug("Duplicate organ in slot \"[limb_name]\", mob '[target]'") owner.organs_by_name[limb_name] = src owner.organs |= src - for(var/obj/item/organ/organ in src) - if(istype(src, /obj/item/organ/internal)) - var/obj/item/organ/internal/I = organ - if(target.get_organ_slot(I.slot)) - continue // Just leave it inside its limb, so brains with brainmobs in them don't get voided. - organ.replaced(owner,src) + for(var/atom/movable/stuff in src) + stuff.attempt_become_organ(src, owner) if(parent_organ) parent = owner.organs_by_name[src.parent_organ] @@ -161,6 +157,12 @@ break parent.update_damages() +/obj/item/organ/external/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H) + if(parent_organ != parent.limb_name) + return 0 + replaced(H) + return 1 + /**************************************************** DAMAGE PROCS ****************************************************/ @@ -691,7 +693,8 @@ Note that amputating the affected organ does in fact remove the infection from t "You hear the [gore_sound].") var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed(). - remove(null, ignore_children) + // Let people make limbs become fun things when removed + var/atom/movable/dropped_part = remove(null, ignore_children) victim.traumatic_shock += 30 wounds.Cut() @@ -726,12 +729,12 @@ Note that amputating the affected organ does in fact remove the infection from t if(!clean) // Throw limb around. if(src && istype(loc,/turf)) - throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) + dropped_part.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) dir = 2 - return + return dropped_part else qdel(src) // If you flashed away to ashes, YOU FLASHED AWAY TO ASHES - return + return null /**************************************************** HELPERS @@ -903,7 +906,7 @@ Note that amputating the affected organ does in fact remove the infection from t var/is_robotic = status & ORGAN_ROBOT var/mob/living/carbon/human/victim = owner - ..() + . = ..() status |= ORGAN_DESTROYED victim.bad_external_organs -= src @@ -914,14 +917,14 @@ Note that amputating the affected organ does in fact remove the infection from t // Attached organs also fly off. if(!ignore_children) for(var/obj/item/organ/external/O in children) - O.remove(victim) - if(O) - O.forceMove(src) + var/atom/movable/thing = O.remove(victim) + if(thing) + thing.forceMove(src) // Grab all the internal giblets too. for(var/obj/item/organ/internal/organ in internal_organs) - organ.remove(victim) - organ.forceMove(src) + var/atom/movable/thing = organ.remove(victim) + thing.forceMove(src) release_restraints(victim) victim.organs -= src diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index 49777aa4a5c..fb945fce7f6 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -47,7 +47,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/head/remove() get_icon() - ..() + . = ..() /obj/item/organ/external/head/get_icon() diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 9c28a60b055..9958e1705c2 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -15,6 +15,11 @@ insert(holder) ..() +/obj/item/organ/internal/Destroy() + if(owner) + remove(owner, 1) + return ..() + /obj/item/organ/internal/proc/insert(mob/living/carbon/M, special = 0, var/dont_remove_slot = 0) if(!iscarbon(M) || owner == M) return @@ -43,7 +48,9 @@ var/datum/action/A = X A.Grant(M) - +// Removes the given organ from its owner. +// Returns the removed object, which is usually just itself +// However, you MUST set the object's positiion yourself when you call this! /obj/item/organ/internal/remove(mob/living/carbon/M, special = 0) owner = null if(M) @@ -63,7 +70,7 @@ for(var/X in actions) var/datum/action/A = X A.Remove(M) - + return src /obj/item/organ/internal/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected) insert(target) @@ -78,11 +85,6 @@ /obj/item/organ/internal/proc/on_life() return -/obj/item/organ/internal/Destroy() - if(owner) - remove(owner, 1) - return ..() - /obj/item/organ/internal/proc/prepare_eat() if(status == ORGAN_ROBOT) return //no eating cybernetic implants! @@ -96,6 +98,12 @@ return S +/obj/item/organ/internal/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H) + if(parent_organ != parent.limb_name) + return 0 + insert(H) + return 1 + /obj/item/weapon/reagent_containers/food/snacks/organ name = "appendix" icon_state = "appendix" @@ -149,7 +157,7 @@ icon_state = "[icon_base]-off" /obj/item/organ/internal/heart/remove(mob/living/carbon/M, special = 0) - ..() + . = ..() if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.stat == DEAD || H.heart_attack) @@ -279,7 +287,7 @@ ///obj/item/organ/internal/lungs/remove(mob/living/carbon/M, special = 0) // owner.losebreath += 10 //insert oxy damage extream here. -// ..() +// . = ..() /obj/item/organ/internal/lungs/process() @@ -436,7 +444,7 @@ A.cure() inflamed = 1 update_icon() - ..() + . = ..() /obj/item/organ/internal/appendix/insert(mob/living/carbon/M, special = 0) ..() @@ -508,7 +516,7 @@ organhonked = world.time /obj/item/organ/internal/honktumor/remove(mob/living/carbon/M, special = 0) - ..() + . = ..() M.mutations.Remove(CLUMSY) M.mutations.Remove(COMICBLOCK) @@ -561,7 +569,7 @@ /obj/item/organ/internal/honktumor/cursed /obj/item/organ/internal/honktumor/cursed/remove(mob/living/carbon/M, special = 0, clean_remove = 0) - ..() + . = ..() if(!clean_remove) visible_message("[src] vanishes into dust, and a [M] emits a loud honk!", "You hear a loud honk.") insert(M) //You're not getting away that easily! diff --git a/code/modules/surgery/organs/organ_stump.dm b/code/modules/surgery/organs/organ_stump.dm index b310a5862fc..9d6c0183cb8 100644 --- a/code/modules/surgery/organs/organ_stump.dm +++ b/code/modules/surgery/organs/organ_stump.dm @@ -22,7 +22,7 @@ /obj/item/organ/external/stump/remove() ..() qdel(src) + return null /obj/item/organ/external/stump/is_usable() return 0 - diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm index 2d15efdd041..61e72743464 100644 --- a/code/modules/surgery/organs/parasites.dm +++ b/code/modules/surgery/organs/parasites.dm @@ -32,4 +32,5 @@ /obj/item/organ/internal/body_egg/spider_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() M.reagents.del_reagent("spidereggs") //purge all remaining spider eggs reagent if caught, in time. - qdel(src) //We don't want people re-implanting these for near instant gibbings. \ No newline at end of file + qdel(src) //We don't want people re-implanting these for near instant gibbings. + return null diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm index 7c84bdc2019..a47ab801d6f 100644 --- a/code/modules/surgery/organs/subtypes/grey.dm +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -12,5 +12,5 @@ M.add_language("Psionic Communication") /obj/item/organ/internal/brain/grey/remove(var/mob/living/carbon/M, var/special = 0) - ..() + . = ..() M.remove_language("Psionic Communication") diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm index d64fbf70e3d..5ea937c0bb1 100644 --- a/code/modules/surgery/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -117,13 +117,6 @@ robotize() ..() -/obj/item/organ/internal/cell/insert() - ..() - // This is very ghetto way of rebooting an IPC. TODO better way. - if(owner && owner.stat == DEAD) - owner.stat = CONSCIOUS - owner.visible_message("\The [owner] twitches visibly!") - /obj/item/organ/internal/optical_sensor name = "optical sensor" organ_tag = "eyes" @@ -167,20 +160,29 @@ species = "Machine" var/obj/item/device/mmi/stored_mmi -/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() - if(!stored_mmi) - return - name = stored_mmi.name - desc = stored_mmi.desc - icon = stored_mmi.icon - icon_state = stored_mmi.icon_state + +/obj/item/organ/internal/brain/mmi_holder/Destroy() + if(stored_mmi) + log_debug("Deleting MMI!") + qdel(stored_mmi) + return ..() + +/obj/item/organ/internal/brain/mmi_holder/insert(var/mob/living/target,special = 0) + ..() + // To supersede the over-writing of the MMI's name from `insert` + update_from_mmi() /obj/item/organ/internal/brain/mmi_holder/remove(var/mob/living/user,special = 0) if(!special) if(stored_mmi) - stored_mmi.forceMove(get_turf(owner)) + . = stored_mmi if(owner.mind) owner.mind.transfer_to(stored_mmi.brainmob) + log_debug("Releasing MMI!") + // move it to nullspace momentarily. If it STAYS there, we got a problem - + // the caller needs to set the location of the removed organ for this to work + contents -= stored_mmi + stored_mmi = null ..() var/mob/living/holder_mob = loc @@ -188,13 +190,14 @@ holder_mob.unEquip(src) qdel(src) -/obj/item/organ/internal/brain/mmi_holder/New() - ..() - // This is very ghetto way of rebooting an IPC. TODO better way. - spawn(1) - if(owner && owner.stat == DEAD) - owner.stat = CONSCIOUS - owner.visible_message("\The [owner] twitches visibly!") +/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() + if(!stored_mmi) + return + name = stored_mmi.name + desc = stored_mmi.desc + icon = stored_mmi.icon + icon_state = stored_mmi.icon_state + set_dna(stored_mmi.brainmob.dna) /obj/item/organ/internal/brain/mmi_holder/posibrain/New() robotize() diff --git a/code/modules/surgery/organs/subtypes/misc.dm b/code/modules/surgery/organs/subtypes/misc.dm index 240a36149f8..be76fa907dc 100644 --- a/code/modules/surgery/organs/subtypes/misc.dm +++ b/code/modules/surgery/organs/subtypes/misc.dm @@ -41,6 +41,7 @@ spawn(0) qdel(src) + return null //VOX ORGANS. /obj/item/organ/internal/stack diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index 1c6240318fe..a82940886be 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -85,7 +85,7 @@ /obj/item/organ/external/foot/remove() if(owner.shoes) owner.unEquip(owner.shoes) - ..() + . = ..() /obj/item/organ/external/foot/right limb_name = "r_foot" @@ -116,7 +116,7 @@ if(owner.r_hand) owner.unEquip(owner.r_hand,1) - ..() + . = ..() /obj/item/organ/external/hand/right limb_name = "r_hand" @@ -178,7 +178,7 @@ if(owner)//runtimer no runtiming owner.update_hair() owner.update_fhair() - ..() + . = ..() /obj/item/organ/external/head/replaced() name = limb_name diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm index 75de3664657..5e771931165 100644 --- a/code/modules/surgery/organs/subtypes/xenos.dm +++ b/code/modules/surgery/organs/subtypes/xenos.dm @@ -24,7 +24,7 @@ M.verbs -= P //M.verbs -= alien_powers.Copy() - ..() + . = ..() /obj/item/organ/internal/xenos/prepare_eat() var/obj/S = ..() @@ -106,7 +106,7 @@ A.updatePlasmaDisplay() /obj/item/organ/internal/alien/plasmavessel/remove(mob/living/carbon/M, special = 0) - ..() + . =..() if(isalien(M)) var/mob/living/carbon/alien/A = M A.updatePlasmaDisplay() @@ -140,7 +140,7 @@ M.faction -= "alien" M.remove_language("Hivemind") M.remove_language("Xenomorph") - ..() + . = ..() /obj/item/organ/internal/xenos/neurotoxin name = "xeno neurotoxin gland" @@ -165,4 +165,4 @@ slot = "eggsac" w_class = 4 origin_tech = "biotech=8" - alien_powers = list(/mob/living/carbon/alien/humanoid/queen/verb/lay_egg) \ No newline at end of file + alien_powers = list(/mob/living/carbon/alien/humanoid/queen/verb/lay_egg) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 625f886455a..8928f52bb47 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -1,5 +1,5 @@ /datum/surgery/organ_manipulation - name = "organ manipulation" + name = "Organ Manipulation" steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw, /datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/manipulate_organs, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) possible_locs = list("chest","head") @@ -11,13 +11,13 @@ requires_organic_bodypart = 1 /datum/surgery/organ_manipulation_boneless - name = "organ manipulation" + name = "Organ Manipulation" possible_locs = list("chest","head","groin", "eyes", "mouth") steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize) requires_organic_bodypart = 1 /datum/surgery/organ_manipulation/alien - name = "alien organ manipulation" + name = "Alien Organ Manipulation" possible_locs = list("chest", "head", "groin", "eyes", "mouth") allowed_mob = list(/mob/living/carbon/alien/humanoid) steps = list(/datum/surgery_step/saw_carapace,/datum/surgery_step/cut_carapace, /datum/surgery_step/retract_carapace,/datum/surgery_step/internal/manipulate_organs) @@ -27,11 +27,12 @@ if(istype(target,/mob/living/carbon/human)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(affected && (affected.status & ORGAN_ROBOT)) + if(!affected) + // I'd like to see you do surgery on LITERALLY NOTHING return 0 - if(target.get_species() == "Machine")//i know organ robot might be enough but i am not taking chances... + if(affected.status & ORGAN_ROBOT) return 0 - if(affected && !affected.encased) //no bone, problem. + if(!affected.encased) //no bone, problem. return 0 return 1 @@ -42,6 +43,9 @@ if(affected && (affected.status & ORGAN_ROBOT)) return 0//no operating on robotic limbs in an organic surgery + if(!affected) + // I'd like to see you do surgery on LITERALLY NOTHING + return 0 if(affected && affected.encased) //no bones no problem. return 0 @@ -236,8 +240,11 @@ add_logs(target,user, "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) + var/obj/item/thing = I.remove(target) + if(!istype(thing)) + thing.forceMove(get_turf(target)) + else + user.put_in_hands(thing) 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)]!") diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 21328599a19..de9d096a628 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -4,15 +4,26 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/infection - name = "external infection treatment/autopsy" + name = "External Infection Treatment/Autopsy" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/cauterize) possible_locs = list("chest","head","groin", "l_arm", "r_arm", "l_leg", "r_leg", "r_hand", "l_hand", "r_foot", "l_foot") /datum/surgery/bleeding - name = "internal bleeding" + name = "Internal Bleeding" steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders,/datum/surgery_step/generic/retract_skin,/datum/surgery_step/fix_vein,/datum/surgery_step/generic/cauterize) possible_locs = list("chest","head","groin", "l_arm", "r_arm", "l_leg", "r_leg", "r_hand", "l_hand", "r_foot", "l_foot") +/datum/surgery/infection/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_ROBOT) + return 0 + return 1 + return 0 + /datum/surgery/bleeding/can_start(mob/user, mob/living/carbon/target) if(ishuman(target)) var/mob/living/carbon/human/H = target @@ -49,7 +60,7 @@ internal_bleeding = 1 break - return affected.open == 2 && internal_bleeding + return internal_bleeding /datum/surgery_step/fix_vein/begin_step(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) @@ -207,35 +218,59 @@ // Dethrall Shadowling // ////////////////////////////////////////////////////////////////// /datum/surgery/remove_thrall - name = "cleanse contaminations"//RENAME MEH + name = "Remove Shadow Tumor" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/dethrall, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) - possible_locs = list("head") + possible_locs = list("head", "chest", "groin") /datum/surgery/remove_thrall/synth - name = "cleanse contaminations"//RENAME MEH steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/internal/dethrall,/datum/surgery_step/robotics/external/close_hatch) - possible_locs = list("chest") + possible_locs = list("head", "chest", "groin") +/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + if(!is_thrall(target)) + return 0 + var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain) + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!B) + // No brain to remove the tumor from + return 0 + if(affected.status & ORGAN_ROBOT) + return 0 + if(!(B in affected.internal_organs)) + return 0 + return 1 - -/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/target) - return is_thrall(target) //would this be too meta? - -/datum/surgery/remove_thrall/synth/can_start(mob/user, mob/living/carbon/target) - return is_thrall(target) && target.get_species() == "Machine" +/datum/surgery/remove_thrall/synth/can_start(mob/user, mob/living/carbon/human/target) + if(!istype(target)) + return 0 + if(!is_thrall(target)) + return 0 + var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain) + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!B) + // No brain to remove the tumor from + return 0 + if(!(affected.status & ORGAN_ROBOT)) + return 0 + if(!(B in affected.internal_organs)) + return 0 + return 1 /datum/surgery_step/internal/dethrall name = "cleanse contamination" allowed_tools = list(/obj/item/device/flash = 100, /obj/item/device/flashlight/pen = 80, /obj/item/device/flashlight = 40) - + blood_level = 0 time = 30 /datum/surgery_step/internal/dethrall/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && is_thrall(target) && affected.open_enough_for_surgery() && target_zone == target.named_organ_parent("brain") + if(!..()) + return 0 + if(!is_thrall(target)) + return 0 + return 1 /datum/surgery_step/internal/dethrall/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/braincase = target.named_organ_parent("brain") @@ -263,11 +298,15 @@ S.apply_damage(20, BRUTE) playsound(S, 'sound/effects/bang.ogg', 50, 1) return 0 - user.visible_message("[user] shines light onto the tumor in [target]'s head!", "You cleanse the contamination from [target]'s brain!") + var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain) + var/obj/item/organ/external/E = target.get_organ(check_zone(B.parent_organ)) + user.visible_message("[user] shines light onto the tumor in [target]'s [E]!", "You cleanse the contamination from [target]'s brain!") if(target.vision_type) //Turns off their darksight if it's still active. to_chat(target, "Your eyes are suddenly wrought with immense pain as your darksight is forcibly dismissed!") target.vision_type = null ticker.mode.remove_thrall(target.mind, 0) - target.visible_message("A strange black mass falls from [target]'s head!") - new /obj/item/organ/internal/shadowtumor(get_turf(target)) + target.visible_message("A strange black mass falls from [target]'s [E]!") + var/obj/item/organ/thing = new /obj/item/organ/internal/shadowtumor(get_turf(target)) + thing.set_dna(target.dna) + user.put_in_hands(thing) return 1 diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 4567c465678..8a07616f5fc 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -5,18 +5,18 @@ /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/external/repair_brute,/datum/surgery_step/robotics/external/repair_burn,/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) 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/internal - name = "Internal Cybernetic Mainpulation" + name = "Internal Component Manipulation" 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("eyes", "chest","head","groin") requires_organic_bodypart = 0 /datum/surgery/cybernetic_amputation - name = "robotic limb amputation" + name = "Robotic Limb Amputation" steps = list(/datum/surgery_step/robotics/external/amputate) 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 @@ -33,7 +33,6 @@ return 1 /datum/surgery/cybernetic_amputation/can_start(mob/user, mob/living/carbon/target) - if(istype(target,/mob/living/carbon/human)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) @@ -41,16 +40,16 @@ return 0 if(!(affected.status & ORGAN_ROBOT)) return 0 + if(affected.cannot_amputate) + return 0 return 1 -//to do, moar surgerys or condense down ala mainpulate organs. +//to do, moar surgerys or condense down ala manipulate organs. /datum/surgery_step/robotics can_infect = 0 /datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(isslime(target)) - return 0 - if(target_zone == "eyes") //there are specific steps for eye surgery + if(!istype(target)) return 0 if(!hasorgans(target)) return 0 @@ -152,7 +151,7 @@ /datum/surgery_step/robotics/external/close_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open && target_zone != "mouth" + return affected && affected.open /datum/surgery_step/robotics/external/close_hatch/begin_step(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) @@ -165,7 +164,6 @@ user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ " You close and secure the hatch on [target]'s [affected.name] with \the [tool].") affected.open = 0 - affected.germ_level = 0 return 1 /datum/surgery_step/robotics/external/close_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -174,94 +172,116 @@ " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") return 0 -/datum/surgery_step/robotics/external/repair_brute - name = "Repair brute damage" - allowed_tools = list( +/datum/surgery_step/robotics/external/repair + name = "repair damage internally" + allowed_tools = list() + + var/list/implements_finish = list( + /obj/item/weapon/retractor = 100, + /obj/item/weapon/crowbar = 100, + /obj/item/weapon/kitchen/utensil = 50 + ) + var/list/implements_heal_burn = list( + /obj/item/stack/cable_coil = 100 + ) + var/list/implements_heal_brute = list( /obj/item/weapon/weldingtool = 100, /obj/item/weapon/gun/energy/plasmacutter = 50 ) - + var/current_type time = 32 -/datum/surgery_step/robotics/external/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/robotics/external/repair/New() + ..() + allowed_tools = implements_heal_burn + implements_heal_brute + implements_finish + + +/datum/surgery_step/robotics/external/repair/begin_step(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) + return -1 + if(affected.open != 2) + to_chat(user, "The [affected] needs to be open to be operated on!") + return -1 + + if(implement_type in implements_heal_burn) + current_type = "burn" + var/obj/item/stack/cable_coil/C = tool + if(!(affected.burn_dam > 0)) + to_chat(user, "The [affected] does not have any burn damage!") + return -1 + if(!istype(C)) + return -1 + if(!C.get_amount() >= 3) + to_chat(user, "You need three or more cable pieces to repair this damage.") + return -1 + C.use(3) + user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \ + "You begin to splice new cabling into [target]'s [affected.name].") + + else if(implement_type in implements_heal_brute) + current_type = "brute" + if(!(affected.brute_dam > 0 || affected.disfigured)) + to_chat(user, "The [affected] does not require welding repair!") + return -1 if(istype(tool,/obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/welder = tool if(!welder.isOn() || !welder.remove_fuel(1,user)) - return 0 - return affected && affected.open == 2 && (affected.brute_dam > 0 || affected.disfigured)&& target_zone != "mouth" + return -1 + user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ + "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") -/datum/surgery_step/robotics/external/repair_brute/begin_step(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) - user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ - "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") + else if(implement_type in implements_finish) + current_type = "finish" + user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \ + "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].") + else + log_debug("Invalid tool: '[implement_type]'") + return -1 ..() -/datum/surgery_step/robotics/external/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) +/datum/surgery_step/robotics/external/repair/end_step(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) - user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ - " 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() - return 1 - -/datum/surgery_step/robotics/external/repair_brute/fail_step(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) - user.visible_message(" [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", - " Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") - target.apply_damage(rand(5,10), BURN, affected) + switch(current_type) + if("brute") + user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ + " 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() + if("burn") + user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \ + " You finishes splicing new cable into [target]'s [affected.name].") + affected.heal_damage(0,rand(30,50),1,1) + if("finish") + user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ + " You close and secure the hatch on [target]'s [affected.name] with \the [tool].") + affected.open = 0 + return 1 return 0 -/datum/surgery_step/robotics/external/repair_burn - name = "repair heat damage" - allowed_tools = list( - /obj/item/stack/cable_coil = 100 - ) - - time = 32 - -/datum/surgery_step/robotics/external/repair_burn/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(..()) - var/obj/item/stack/cable_coil/C = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth") - if(limb_can_operate) - if(istype(C)) - if(!C.get_amount() >= 3) - to_chat(user, "You need three or more cable pieces to repair this damage.") - return 2 - C.use(3) - return 1 - return 0 - -/datum/surgery_step/robotics/external/repair_burn/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) +/datum/surgery_step/robotics/external/repair/fail_step(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) - user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \ - "You begin to splice new cabling into [target]'s [affected.name].") - ..() - -/datum/surgery_step/robotics/external/repair_burn/end_step(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) - user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \ - " You finishes splicing new cable into [target]'s [affected.name].") - affected.heal_damage(0,rand(30,50),1,1) - return 1 - -/datum/surgery_step/robotics/external/repair_burn/fail_step(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) - user.visible_message(" [user] causes a short circuit in [target]'s [affected.name]!", - " You cause a short circuit in [target]'s [affected.name]!") - target.apply_damage(rand(5,10), BURN, affected) + switch(current_type) + if("brute") + user.visible_message(" [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", + " Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") + target.apply_damage(rand(5,10), BURN, affected) + if("burn") + user.visible_message(" [user] causes a short circuit in [target]'s [affected.name]!", + " You cause a short circuit in [target]'s [affected.name]!") + target.apply_damage(rand(5,10), BURN, affected) + if("finish") + user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", + " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") return 0 ///////condenseing remove/extract/repair here. ///////////// /datum/surgery_step/robotics/manipulate_robotic_organs - name = "internal part mainpulation" + name = "internal part manipulation" 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) @@ -423,29 +443,23 @@ " 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) + M.attempt_become_organ(affected,target) else if(current_type == "extract") if(I && I.owner == target) - user.visible_message(" [user] has decoupled [target]'s [surgery.current_organ] with \the [tool]." , \ - " You have decoupled [target]'s [surgery.current_organ] with \the [tool].") + user.visible_message(" [user] has decoupled [target]'s [I] with \the [tool]." , \ + " You have decoupled [target]'s [I] with \the [tool].") add_logs(target,user, "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) + var/obj/item/thing = I.remove(target) + if(!istype(thing)) + thing.forceMove(get_turf(target)) + else + user.put_in_hands(thing) 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)]!") @@ -490,81 +504,9 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") - return -1 + return 0 - -/datum/surgery_step/robotics/install_mmi - allowed_tools = list( - /obj/item/device/mmi = 100 - ) - - time = 64 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - - if(target_zone != "chest") - return 0 - - var/obj/item/device/mmi/M = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && affected.open_enough_for_surgery())) - return 0 - - if(!istype(M)) - return 0 - - if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) - to_chat(user, "That brain is not usable.") - return 2 - - if(!(affected.status & ORGAN_ROBOT)) - to_chat(user, "You cannot install a computer brain into a meat enclosure.") - return 2 - - if(!target.species) - to_chat(user, "You have no idea what species this person is. Report this on the bug tracker.") - return 2 - - if(!target.species.has_organ["brain"]) - to_chat(user, "You're pretty sure [target.species.name_plural] don't normally have a brain.") - return 2 - - if(target.get_int_organ(/obj/item/organ/internal/brain/)) - to_chat(user, "Your subject already has a brain.") - return 2 - - return 1 - - begin_step(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) - user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ - "You start installing \the [tool] into [target]'s [affected.name].") - ..() - - end_step(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) - user.visible_message(" [user] has installed \the [tool] into [target]'s [affected.name].", \ - " 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) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message(" [user]'s hand slips.", \ - " Your hand slips.") - /datum/surgery_step/robotics/external/amputate name = "remove robotic limb" @@ -589,11 +531,14 @@ add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it - affected.droplimb(1,DROPLIMB_EDGE) + var/atom/movable/thing = affected.droplimb(1,DROPLIMB_EDGE) + if(istype(thing,/obj/item)) + user.put_in_hands(thing) + return 1 /datum/surgery_step/robotics/external/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message(" [user]'s hand slips!", \ " Your hand slips!") - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 8a60718ccbf..bbde2f3fd32 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -43,7 +43,7 @@ /datum/surgery/proc/complete(mob/living/carbon/human/target) target.surgeries -= src - src = null + qdel(src) @@ -95,6 +95,8 @@ return 0 /datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(!can_use(user, target, target_zone, tool, surgery)) + return surgery.step_in_progress = 1 if(begin_step(user, target, target_zone, tool, surgery) == -1) @@ -110,7 +112,7 @@ if(prob_chance > 100)//if we are using a super tool time = time/prob_chance //PLACEHOLDER VALUES - + time = 1 // DEBUG LINE if(do_after(user, time, target = target)) @@ -154,7 +156,7 @@ // checks whether this step can be applied with the given user and target /datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - return 0 + return 1 // does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too /datum/surgery_step/proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)