From 9fa9f402147f1ac5ac0e1f55f54211a58269440a Mon Sep 17 00:00:00 2001 From: Crazylemon Date: Wed, 16 Dec 2015 17:53:37 -0800 Subject: [PATCH 1/5] First test of preventing multibrain shenanigans --- .../mob/living/carbon/brain/brain_item.dm | 32 +++++++++++++------ code/modules/mob/living/carbon/brain/life.dm | 2 +- code/modules/organs/organ.dm | 16 +++++++--- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 10b8d580447..e06d9d3788e 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -69,23 +69,35 @@ owner.brain_op_stage = 4.0 var/obj/item/organ/brain/B = src - if(istype(B) && istype(owner)) + if(istype(B) && istype(owner) && owner.internal_organs_by_name[organ_tag] == src) B.transfer_identity(owner) ..() /obj/item/organ/brain/replaced(var/mob/living/target) - if(target.key) - target.ghostize() - var/mob/living/carbon/C = target - if(istype(C)) - C.brain_op_stage = 1.0 + var/brain_already_exists = 0 + if(istype(target,/mob/living/carbon/human)) // No more IPC multibrain shenanigans + var/mob/living/carbon/human/H = target + if(organ_tag in H.internal_organs_by_name) + brain_already_exists = 1 + + if(!brain_already_exists) + if(target.key) + target.ghostize() + var/mob/living/carbon/C = target + if(istype(C)) + C.brain_op_stage = 1.0 + if(brainmob) + if(brainmob.mind) + brainmob.mind.transfer_to(target) + else + target.key = brainmob.key + ..() + +/obj/item/organ/brain/die() if(brainmob) - if(brainmob.mind) - brainmob.mind.transfer_to(target) - else - target.key = brainmob.key + brainmob.death(0) ..() /obj/item/organ/brain/slime diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 2a191c46217..1a3ccdf0ca6 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -4,7 +4,7 @@ radiation -= 3 adjustToxLoss(3) updatehealth() - if(!container) + if(!container) // The brains are containers - Theory: Everyone on the station is secretly a highly-advanced cyborg, wearing meat shells src << "You feel weak." else src << "STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED." diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index e7d4fd89eba..5176f1a02d8 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -257,12 +257,17 @@ var/list/organ_cache = list() /obj/item/organ/proc/removed(var/mob/living/user) + var/primary_organ = 1 if(!istype(owner)) return - owner.internal_organs_by_name[organ_tag] = null - owner.internal_organs_by_name -= organ_tag - owner.internal_organs_by_name -= null + if(owner.internal_organs_by_name[organ_tag] == src) + owner.internal_organs_by_name[organ_tag] = null + owner.internal_organs_by_name -= organ_tag + owner.internal_organs_by_name -= null + else + primary_organ = 0 + owner.internal_organs -= src var/obj/item/organ/external/affected = owner.get_organ(parent_organ) @@ -275,7 +280,7 @@ var/list/organ_cache = list() if(!organ_blood || !organ_blood.data["blood_DNA"]) owner.vessel.trans_to(src, 5, 1, 1) - if(owner && vital) + if(owner && vital && primary_organ) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead if(user) user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [key_name(owner)] (INTENT: [uppertext(user.a_intent)])" owner.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [key_name(user)] (INTENT: [uppertext(user.a_intent)])" @@ -291,7 +296,8 @@ var/list/organ_cache = list() processing_objects -= src target.internal_organs |= src affected.internal_organs |= src - target.internal_organs_by_name[organ_tag] = src + if (!(organ_tag in target.internal_organs_by_name)) + target.internal_organs_by_name[organ_tag] = src // In case multiple of the same type are inserted, only the first one is the primary organ src.loc = target if(robotic) status |= ORGAN_ROBOT From 26545e6ba1fe01c909948e03c452a57807fbe6df Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Wed, 16 Dec 2015 23:01:28 -0800 Subject: [PATCH 2/5] Fixed up organ surgery so it'd reflect organs properly This will work in spite of the states, so that sticking a human head on an IPC will still let you remove the brain from that useless head, without giving the brain any silly names --- .../mob/living/carbon/brain/brain_item.dm | 6 +-- code/modules/surgery/organs_internal.dm | 44 ++++++++++++------- code/modules/surgery/robotics.dm | 20 +++++---- code/modules/surgery/surgery.dm | 1 + 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index e06d9d3788e..38a74cb8c1c 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -59,7 +59,6 @@ /obj/item/organ/brain/removed(var/mob/living/user) if(!owner) return ..() // Probably a redundant removal; just bail - name = "[owner.real_name]'s brain" var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() @@ -96,8 +95,9 @@ ..() /obj/item/organ/brain/die() - if(brainmob) - brainmob.death(0) + // Brains dying kills the internal consciousness +// if(brainmob) +// qdel(brainmob) I'll leave this in for my next PR, and so people can yell at me about it ..() /obj/item/organ/brain/slime diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index b0b840d138c..f3a5abd2ac8 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -206,18 +206,20 @@ return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/attached_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - attached_organs |= organ + attached_organs[I.organ_tag] = I var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs if(!organ_to_remove) return 0 target.op_stage.current_organ = organ_to_remove + target.op_stage.organ_ref = attached_organs[organ_to_remove] return ..() && organ_to_remove @@ -234,7 +236,7 @@ user.visible_message("\blue [user] has separated [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have separated [target]'s [target.op_stage.current_organ] with \the [tool].") - var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.op_stage.organ_ref if(I && istype(I)) I.status |= ORGAN_CUT_AWAY @@ -259,20 +261,26 @@ if (!..()) return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + if(!istype(affected)) + return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/removable_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] - if((I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - removable_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(istype(I) && (I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + removable_organs[I.organ_tag] = I var/organ_to_remove = input(user, "Which organ do you want to remove?") as null|anything in removable_organs if(!organ_to_remove) return 0 target.op_stage.current_organ = organ_to_remove + target.op_stage.organ_ref = removable_organs[organ_to_remove] return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -287,10 +295,9 @@ // Extract the organ! if(target.op_stage.current_organ) - var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/O = target.op_stage.organ_ref if(O && istype(O)) O.removed(user) - target.op_stage.current_organ = null 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) @@ -391,19 +398,26 @@ if (!..()) return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + if(!istype(affected)) + return 0 + target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/removable_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(I && istype(I) && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) + removable_organs[I.organ_tag] = I var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs if(!organ_to_replace) return 0 target.op_stage.current_organ = organ_to_replace + target.op_stage.organ_ref = removable_organs[organ_to_replace] return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -416,7 +430,7 @@ user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/I = target.op_stage.organ_ref if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index fa6fd6f215f..cf2fe5cd6a4 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -289,18 +289,20 @@ return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/attached_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - attached_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(I && istype(I) && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + attached_organs[I.organ_tag] = I var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs if(!organ_to_remove) return 0 target.op_stage.current_organ = organ_to_remove + target.op_stage.organ_ref = attached_organs[organ_to_remove] return ..() && organ_to_remove @@ -338,18 +340,20 @@ return 0 target.op_stage.current_organ = null + target.op_stage.organ_ref = null var/list/removable_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs |= organ + for(var/organ in affected.internal_organs) + var/obj/item/organ/I = organ + if(I && istype(I) && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) + removable_organs[I.organ_tag] = I var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs if(!organ_to_replace) return 0 target.op_stage.current_organ = organ_to_replace + target.op_stage.organ_ref = removable_organs[organ_to_replace] return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index d353c4f49f7..6b7d0fe1456 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -131,4 +131,5 @@ var/ribcage = 0 var/head_reattach = 0 var/current_organ = "organ" + var/obj/item/organ/organ_ref = null var/list/in_progress = list() \ No newline at end of file From 8deec9b0a488810b23d7e3afba89012e0872ef3f Mon Sep 17 00:00:00 2001 From: Crazy Lemon Date: Thu, 17 Dec 2015 00:07:58 -0800 Subject: [PATCH 3/5] Update life.dm --- code/modules/mob/living/carbon/brain/life.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 1a3ccdf0ca6..b2869cb96c2 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -4,7 +4,7 @@ radiation -= 3 adjustToxLoss(3) updatehealth() - if(!container) // The brains are containers - Theory: Everyone on the station is secretly a highly-advanced cyborg, wearing meat shells + if(!container) src << "You feel weak." else src << "STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED." @@ -99,4 +99,4 @@ var/obj/mecha/piloted = mmi.mecha piloted.pilot_mmi_hud(src) - handle_hud_icons_health() \ No newline at end of file + handle_hud_icons_health() From d63f1607c3e7c2d1c08493d39c0d0576823b0b18 Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Thu, 17 Dec 2015 00:42:23 -0800 Subject: [PATCH 4/5] No more surviving rayman reenactments --- code/modules/organs/organ.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 5176f1a02d8..ce26098a1e7 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -265,6 +265,10 @@ var/list/organ_cache = list() owner.internal_organs_by_name[organ_tag] = null owner.internal_organs_by_name -= organ_tag owner.internal_organs_by_name -= null + else if(istype(src,/obj/item/organ/external)) // Limbs being a subtype of internal organs is dumb + var/obj/item/organ/external/E = src + if(owner.organs_by_name[E.limb_name] != src) + primary_organ = 0 else primary_organ = 0 From 860275f51d6ff31d86987738562657ca84089c53 Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Thu, 17 Dec 2015 22:42:28 -0800 Subject: [PATCH 5/5] Splits the primary organ checking into another function Also fixes the head and brain renaming so it works off of DNA instead of the body you took it of --- .../mob/living/carbon/brain/brain_item.dm | 33 +++++++++---------- code/modules/organs/organ.dm | 28 +++++++++------- code/modules/organs/organ_external.dm | 10 +++++- code/modules/organs/subtypes/standard.dm | 2 +- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 38a74cb8c1c..5a0132f6bd8 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -37,11 +37,15 @@ brainmob.client.screen.len = null //clear the hud /obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H) - name = "\the [H]'s [initial(src.name)]" brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() + if(isnull(dna)) // someone didn't set this right... + log_to_dd("[src] at [loc] did not contain a dna datum at time of removed.") + dna = H.dna.Clone() + name = "\the [dna.real_name]'s [initial(src.name)]" + brainmob.dna = dna.Clone() // Silly baycode, what you do +// brainmob.dna = H.dna.Clone() Putting in and taking out a brain doesn't make it a carbon copy of the original brain of the body you put it in + brainmob.name = dna.real_name + brainmob.real_name = dna.real_name brainmob.timeofhostdeath = H.timeofdeath if(H.mind) H.mind.transfer_to(brainmob) @@ -60,15 +64,14 @@ if(!owner) return ..() // Probably a redundant removal; just bail - var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() - - if(borer) - borer.detatch() //Should remove borer if the brain is removed - RR - - owner.brain_op_stage = 4.0 - var/obj/item/organ/brain/B = src - if(istype(B) && istype(owner) && owner.internal_organs_by_name[organ_tag] == src) + if(istype(B) && istype(owner) && is_primary_organ()) + var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() + + if(borer) + borer.detatch() //Should remove borer if the brain is removed - RR + + owner.brain_op_stage = 4.0 B.transfer_identity(owner) ..() @@ -94,12 +97,6 @@ target.key = brainmob.key ..() -/obj/item/organ/brain/die() - // Brains dying kills the internal consciousness -// if(brainmob) -// qdel(brainmob) I'll leave this in for my next PR, and so people can yell at me about it - ..() - /obj/item/organ/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index ce26098a1e7..62449b727c1 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -256,21 +256,13 @@ var/list/organ_cache = list() take_damage(0,3) /obj/item/organ/proc/removed(var/mob/living/user) - - var/primary_organ = 1 if(!istype(owner)) return - if(owner.internal_organs_by_name[organ_tag] == src) + if(is_primary_organ()) owner.internal_organs_by_name[organ_tag] = null owner.internal_organs_by_name -= organ_tag - owner.internal_organs_by_name -= null - else if(istype(src,/obj/item/organ/external)) // Limbs being a subtype of internal organs is dumb - var/obj/item/organ/external/E = src - if(owner.organs_by_name[E.limb_name] != src) - primary_organ = 0 - else - primary_organ = 0 + owner.internal_organs_by_name -= null // uh what does this line even do this seems silly owner.internal_organs -= src @@ -284,7 +276,7 @@ var/list/organ_cache = list() if(!organ_blood || !organ_blood.data["blood_DNA"]) owner.vessel.trans_to(src, 5, 1, 1) - if(owner && vital && primary_organ) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead + if(owner && vital && is_primary_organ()) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead if(user) user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [key_name(owner)] (INTENT: [uppertext(user.a_intent)])" owner.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [key_name(user)] (INTENT: [uppertext(user.a_intent)])" @@ -336,4 +328,16 @@ var/list/organ_cache = list() qdel(src) /obj/item/organ/proc/surgeryize() - return \ No newline at end of file + return + +/* +Returns 1 if this is the organ that is handling all the functionalities of that particular organ slot +Returns 0 if it isn't +I use this so that this can be made better once the organ overhaul rolls out -- Crazylemon +*/ +/obj/item/organ/proc/is_primary_organ(var/mob/living/carbon/human/O = null) + if (isnull(O)) + O = owner + if (!istype(owner)) // You're not the primary organ of ANYTHING, bucko + return 0 + return src == O.internal_organs_by_name[organ_tag] \ No newline at end of file diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 1c6ca1d176b..e1ab07b028e 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -855,7 +855,8 @@ Note that amputating the affected organ does in fact remove the infection from t release_restraints(victim) victim.organs -= src - victim.organs_by_name[limb_name] = null // Remove from owner's vars. + if(is_primary_organ(victim)) + victim.organs_by_name[limb_name] = null // Remove from owner's vars. //Robotic limbs explode if sabotaged. if(is_robotic && sabotaged) @@ -885,3 +886,10 @@ Note that amputating the affected organ does in fact remove the infection from t "\red Your [name] melts away!", \ "\red You hear a sickening sizzle.") disfigured = 1 + +/obj/item/organ/external/is_primary_organ(var/mob/living/carbon/human/O = null) + if (isnull(O)) + O = owner + if (!istype(O)) // You're not the primary organ of ANYTHING, bucko + return 0 + return src == O.organs_by_name[limb_name] diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index 6663f833bef..c11b8e028ab 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -137,7 +137,7 @@ /obj/item/organ/external/head/removed() if(owner) - name = "[owner.real_name]'s head" + name = "[dna.real_name]'s head" owner.unEquip(owner.glasses) owner.unEquip(owner.head) owner.unEquip(owner.l_ear)