From 4b030f30cdb8a0767e92b48fb25c0ab7ef999f63 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 24 Dec 2014 15:38:45 +1030 Subject: [PATCH] Refactors and fixes a fair bit of organ transplanting/reattachment/gibbing code. Also fixes an issue with species HUDs. --- code/game/machinery/kitchen/gibber.dm | 2 +- code/modules/mob/death.dm | 2 +- .../mob/living/carbon/brain/brain_item.dm | 1 + code/modules/mob/living/carbon/brain/death.dm | 4 +- code/modules/mob/living/carbon/human/death.dm | 25 +--- code/modules/mob/living/carbon/human/human.dm | 15 ++- code/modules/organs/organ_external.dm | 123 ++++++------------ code/modules/organs/organ_internal.dm | 1 + code/modules/organs/organ_objects.dm | 57 ++++++-- code/modules/surgery/headreattach.dm | 10 +- code/modules/surgery/organs_internal.dm | 42 +----- 11 files changed, 117 insertions(+), 165 deletions(-) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index e81b27fbb35..52c1bdc380f 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -233,7 +233,7 @@ del(thing) continue thing.loc = get_turf(thing) // Drop it onto the turf for throwing. - thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),emagged ? 15 : 30) // Being pelted with bits of meat and bone would hurt. + thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt. update_icon() diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index ab9c64eebfe..3d96e3d9c0c 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -52,7 +52,7 @@ if(stat == DEAD) return 0 - if(!gibbed) + if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it. src.visible_message("\The [src.name] [deathmessage]") stat = DEAD diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 5c22c47bab2..c921c88afd0 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -73,6 +73,7 @@ brainmob.mind.transfer_to(target) else target.key = brainmob.key + ..() /obj/item/organ/brain/slime name = "slime core" diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index ecb729ece90..517e32362a9 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -1,7 +1,9 @@ /mob/living/carbon/brain/death(gibbed) if(!gibbed && istype(container, /obj/item/device/mmi)) //If not gibbed but in a container. container.icon_state = "mmi_dead" - return ..(gibbed,"beeps shrilly as the MMI flatlines!") + return ..(gibbed,"beeps shrilly as the MMI flatlines!") + else + return ..(gibbed,"no message") /mob/living/carbon/brain/gib() if(istype(container, /obj/item/device/mmi)) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 7bc0fc51fb3..ef0a507c204 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -1,5 +1,12 @@ /mob/living/carbon/human/gib() + for(var/datum/organ/internal/I in internal_organs) + var/obj/item/organ/current_organ = I.remove() + if(current_organ) + if(istype(loc,/turf)) + current_organ.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) + current_organ.removed(src) + for(var/datum/organ/external/E in src.organs) if(istype(E, /datum/organ/external/chest)) continue @@ -8,24 +15,6 @@ // Override the current limb status and don't cause an explosion E.droplimb(1,1) - for(var/datum/organ/internal/I in internal_organs) - var/obj/item/organ/current_organ = I.remove() - current_organ.loc = src.loc - current_organ.organ_data.rejecting = null - var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in current_organ.reagents.reagent_list - if(!organ_blood || !organ_blood.data["blood_DNA"]) - src.vessel.trans_to(current_organ, 5, 1, 1) - - current_organ.removed(src) - - if(current_organ && istype(loc,/turf)) - var/target_dir = pick(cardinal) - var/turf/target_turf = loc - var/steps = rand(1,2) - for(var/i = 0;ihead - brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - if(H.mind) - H.mind.transfer_to(brainmob) - brainmob.container = src - -obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/scalpel)) - switch(brain_op_stage) - if(0) - for(var/mob/O in (oviewers(brainmob) - user)) - O.show_message("\red [brainmob] is beginning to have \his head cut open with [W] by [user].", 1) - brainmob << "\red [user] begins to cut open your head with [W]!" - user << "\red You cut [brainmob]'s head open with [W]!" - - brain_op_stage = 1 - - if(2) - for(var/mob/O in (oviewers(brainmob) - user)) - O.show_message("\red [brainmob] is having \his connections to the brain delicately severed with [W] by [user].", 1) - brainmob << "\red [user] begins to cut open your head with [W]!" - user << "\red You cut [brainmob]'s head open with [W]!" - - brain_op_stage = 3.0 - else - ..() - else if(istype(W,/obj/item/weapon/circular_saw)) - switch(brain_op_stage) - if(1) - for(var/mob/O in (oviewers(brainmob) - user)) - O.show_message("\red [brainmob] has \his head sawed open with [W] by [user].", 1) - brainmob << "\red [user] begins to saw open your head with [W]!" - user << "\red You saw [brainmob]'s head open with [W]!" - - brain_op_stage = 2 - if(3) - for(var/mob/O in (oviewers(brainmob) - user)) - O.show_message("\red [brainmob] has \his spine's connection to the brain severed with [W] by [user].", 1) - brainmob << "\red [user] severs your brain's connection to the spine with [W]!" - user << "\red You sever [brainmob]'s brain's connection to the spine with [W]!" - - user.attack_log += "\[[time_stamp()]\] Debrained [brainmob.name] ([brainmob.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)])" - brainmob.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)])" - msg_admin_attack("[user] ([user.ckey]) debrained [brainmob] ([brainmob.ckey]) (INTENT: [uppertext(user.a_intent)]) (JMP)") - - //TODO: ORGAN REMOVAL UPDATE. - if(istype(src,/obj/item/weapon/organ/head/posi)) - var/obj/item/device/mmi/digital/posibrain/B = new(loc) - B.transfer_identity(brainmob) +obj/item/weapon/organ/attackby(obj/item/weapon/W as obj, mob/user as mob) + switch(op_stage) + if(0) + if(istype(W,/obj/item/weapon/scalpel)) + user.visible_message("[user] cuts [src] open with [W]!") + op_stage++ + return + if(1) + if(istype(W,/obj/item/weapon/retractor)) + user.visible_message("[user] cracks [src] open like an egg with [W]!") + op_stage++ + return + if(2) + if(istype(W,/obj/item/weapon/hemostat)) + if(contents.len) + var/obj/item/removing = pick(contents) + removing.loc = src.loc + if(istype(removing,/obj/item/organ)) + var/obj/item/organ/removed_organ = removing + organs_internal -= removed_organ.organ_data + user.visible_message("[user] extracts [removing] from [src] with [W]!") else - var/obj/item/organ/brain/B = new(loc) - B.transfer_identity(brainmob) - - brain_op_stage = 4.0 - else - ..() - else - ..() + user.visible_message("[user] fishes around fruitlessly in [src] with [W].") + return + ..() \ No newline at end of file diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index ef1b6e2116b..b6154242b9a 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -16,6 +16,7 @@ var/rejecting // Is this organ already being rejected? var/obj/item/organ/organ_holder // If not in a body, held in this item. var/list/transplant_data + /datum/organ/internal/proc/rejuvenate() damage=0 diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm index b0e0963fef1..610e702ad12 100644 --- a/code/modules/organs/organ_objects.dm +++ b/code/modules/organs/organ_objects.dm @@ -151,11 +151,24 @@ /obj/item/organ/appendix name = "appendix" -/obj/item/organ/proc/removed(var/mob/living/target,var/mob/living/user) +/obj/item/organ/proc/removed(var/mob/living/carbon/human/target,var/mob/living/user) - if(!target) + if(!istype(target) || !organ_data) return + target.internal_organs_by_name[organ_tag] = null + target.internal_organs_by_name -= organ_tag + target.internal_organs -= organ_data + + var/datum/organ/external/affected = target.get_organ(organ_data.parent_organ) + affected.internal_organs -= organ_data + + loc = target.loc + organ_data.rejecting = null + var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list + if(!organ_blood || !organ_blood.data["blood_DNA"]) + target.vessel.trans_to(src, 5, 1, 1) + if(target && user && organ_data.vital) user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)])" target.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])" @@ -196,18 +209,40 @@ H.b_eyes = 0 H.update_body() -/obj/item/organ/proc/replaced(var/mob/living/target) - return +/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/datum/organ/external/affected) -/obj/item/organ/eyes/replaced(var/mob/living/target) + if(!istype(target)) return + + var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list + if(!transplant_blood) + organ_data.transplant_data = list() + organ_data.transplant_data["species"] = target.species.name + organ_data.transplant_data["blood_type"] = target.dna.b_type + organ_data.transplant_data["blood_DNA"] = target.dna.unique_enzymes + else + organ_data.transplant_data = list() + organ_data.transplant_data["species"] = transplant_blood.data["species"] + organ_data.transplant_data["blood_type"] = transplant_blood.data["blood_type"] + organ_data.transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"] + + organ_data.organ_holder = null + organ_data.owner = target + target.internal_organs |= organ_data + affected.internal_organs |= organ_data + target.internal_organs_by_name[organ_tag] = organ_data + organ_data.status |= ORGAN_CUT_AWAY + + del(src) + +/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) // Apply our eye colour to the target. - var/mob/living/carbon/human/H = target - if(istype(H) && eye_colour) - H.r_eyes = eye_colour[1] - H.g_eyes = eye_colour[2] - H.b_eyes = eye_colour[3] - H.update_body() + if(istype(target) && eye_colour) + target.r_eyes = eye_colour[1] + target.g_eyes = eye_colour[2] + target.b_eyes = eye_colour[3] + target.update_body() + ..() /obj/item/organ/proc/bitten(mob/user) diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index 80899aeee72..76ad0b62018 100644 --- a/code/modules/surgery/headreattach.dm +++ b/code/modules/surgery/headreattach.dm @@ -181,11 +181,11 @@ target.update_body() target.updatehealth() target.UpdateDamageIcon() - var/obj/item/weapon/organ/head/B = tool - if (B.brainmob.mind) - B.brainmob.mind.transfer_to(target) - del(B) - + for(var/obj/item/organ/replacing_organ in tool) + replacing_organ.loc = get_turf(tool) + replacing_organ.replaced(target,affected) + del(replacing_organ) //Just in case. + del(tool) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index b5fbb3ecb06..c6e27d1e04e 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -314,30 +314,12 @@ // Extract the organ! if(target.op_stage.current_organ) - - var/datum/organ/external/affected = target.get_organ(target_zone) var/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] - var/obj/item/organ/O if(I && istype(I)) O = I.remove(user) if(O && istype(O)) - - // Stop the organ from continuing to reject. - O.organ_data.rejecting = null - - // Transfer over some blood data, if the organ doesn't have data. - var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in O.reagents.reagent_list - if(!organ_blood || !organ_blood.data["blood_DNA"]) - target.vessel.trans_to(O, 5, 1, 1) - - // Kinda redundant, but I'm getting some buggy behavior. - target.internal_organs_by_name[target.op_stage.current_organ] = null - target.internal_organs_by_name -= target.op_stage.current_organ - target.internal_organs -= O.organ_data - affected.internal_organs -= O.organ_data O.removed(target,user) - target.op_stage.current_organ = null fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -409,30 +391,8 @@ "\blue You have transplanted \the [tool] into [target]'s [affected.display_name].") user.drop_item(tool) var/obj/item/organ/O = tool - if(istype(O)) - - var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in O.reagents.reagent_list - if(!transplant_blood) - O.organ_data.transplant_data = list() - O.organ_data.transplant_data["species"] = target.species.name - O.organ_data.transplant_data["blood_type"] = target.dna.b_type - O.organ_data.transplant_data["blood_DNA"] = target.dna.unique_enzymes - else - O.organ_data.transplant_data = list() - O.organ_data.transplant_data["species"] = transplant_blood.data["species"] - O.organ_data.transplant_data["blood_type"] = transplant_blood.data["blood_type"] - O.organ_data.transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"] - - O.organ_data.organ_holder = null - O.organ_data.owner = target - target.internal_organs |= O.organ_data - affected.internal_organs |= O.organ_data - target.internal_organs_by_name[O.organ_tag] = O.organ_data - O.organ_data.status |= ORGAN_CUT_AWAY - O.replaced(target) - - del(O) + O.replaced(target,affected) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("\red [user]'s hand slips, damaging \the [tool]!", \