diff --git a/baystation12.dme b/baystation12.dme index d09a530659b..1c200c9afc0 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -292,6 +292,7 @@ #include "code\game\machinery\Beacon.dm" #include "code\game\machinery\bees_apiary.dm" #include "code\game\machinery\bees_items.dm" +#include "code\game\machinery\bioprinter.dm" #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" #include "code\game\machinery\cloning.dm" @@ -1110,6 +1111,7 @@ #include "code\modules\organs\organ.dm" #include "code\modules\organs\organ_external.dm" #include "code\modules\organs\organ_internal.dm" +#include "code\modules\organs\organ_objects.dm" #include "code\modules\organs\pain.dm" #include "code\modules\organs\wound.dm" #include "code\modules\paperwork\carbonpaper.dm" @@ -1345,17 +1347,18 @@ #include "code\modules\shuttles\shuttle_supply.dm" #include "code\modules\shuttles\shuttles_multi.dm" #include "code\modules\supermatter\supermatter.dm" -#include "code\modules\surgery\appendix.dm" #include "code\modules\surgery\bones.dm" -#include "code\modules\surgery\braincore.dm" +#include "code\modules\surgery\brainrepair.dm" +#include "code\modules\surgery\encased.dm" #include "code\modules\surgery\eye.dm" #include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" #include "code\modules\surgery\headreattach.dm" #include "code\modules\surgery\implant.dm" +#include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" -#include "code\modules\surgery\ribcage.dm" #include "code\modules\surgery\robolimbs.dm" +#include "code\modules\surgery\slimes.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\vehicles\cargo_train.dm" #include "code\modules\vehicles\train.dm" diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index 98ab1278257..6cd983732ba 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -117,13 +117,17 @@ obj/var/contaminated = 0 /mob/living/carbon/human/proc/burn_eyes() //The proc that handles eye burning. - if(prob(20)) src << "\red Your eyes burn!" + if(!species.has_organ["eyes"]) + return + var/datum/organ/internal/eyes/E = internal_organs_by_name["eyes"] - E.damage += 2.5 - eye_blurry = min(eye_blurry+1.5,50) - if (prob(max(0,E.damage - 15) + 1) &&!eye_blind) - src << "\red You are blinded!" - eye_blind += 20 + if(E) + if(prob(20)) src << "\red Your eyes burn!" + E.damage += 2.5 + eye_blurry = min(eye_blurry+1.5,50) + if (prob(max(0,E.damage - 15) + 1) &&!eye_blind) + src << "\red You are blinded!" + eye_blind += 20 /mob/living/carbon/human/proc/pl_head_protected() //Checks if the head is adequately sealed. diff --git a/code/controllers/hooks-defs.dm b/code/controllers/hooks-defs.dm index 1cd7c4aad8a..d36fc7a7c7f 100644 --- a/code/controllers/hooks-defs.dm +++ b/code/controllers/hooks-defs.dm @@ -33,7 +33,7 @@ /** * Debrained hook. * Called in brain_item.dm when someone gets debrained. - * Parameters: var/obj/item/brain + * Parameters: var/obj/item/organ/brain */ /hook/debrain diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index dba42d74d64..a9959ef0636 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -19,7 +19,8 @@ if(istype(affected_mob,/mob/living/carbon/human)) var/mob/living/carbon/human/H = affected_mob - if(H.species.name == "Diona" || H.species.name == "Machine" || H.species.name == "Vox") src.cure() + if(!H.internal_organs_by_name["appendix"]) + src.cure() if(stage == 1) if(affected_mob.op_stage.appendix == 2.0) diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index ac85b18ae3b..496eac91956 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -26,8 +26,8 @@ if("gib_brain") if(ishuman(target) || ismonkey(target)) var/mob/living/carbon/C = target - if(C.brain_op_stage != 4) // Their brain is already taken out - var/obj/item/brain/B = new(C.loc) + if(!C.has_brain()) // Their brain is already taken out + var/obj/item/organ/brain/B = new(C.loc) B.transfer_identity(C) target.gib() if("disintegrate") diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 6750f7c83eb..590df9cd07d 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -568,8 +568,8 @@ var/list/sacrificed = list() if(!(iscultist(V))) victims += V//Checks for cult status and mob type for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/brain)) - var/obj/item/brain/B = I + if(istype(I,/obj/item/organ/brain)) + var/obj/item/organ/brain/B = I victims += B.brainmob else if(istype(I,/obj/item/device/mmi)) var/obj/item/device/mmi/B = I diff --git a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm b/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm index 63c3f7d3c86..e035b665c9f 100644 --- a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm +++ b/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm @@ -62,11 +62,11 @@ datum/directive/ipc_virus/get_remaining_orders() return text -/hook/debrain/proc/debrain_directive(obj/item/brain/B) +/hook/debrain/proc/debrain_directive(var/obj/item/organ/brain/B) var/datum/directive/ipc_virus/D = get_directive("ipc_virus") if (!D) return 1 - if(D.brains_to_enslave.Find(B.brainmob.mind)) + if(B && B.brainmob && B.brainmob.mind && D.brains_to_enslave.Find(B.brainmob.mind)) D.brains_to_enslave.Remove(B.brainmob.mind) return 1 diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 70901add189..c2608cfa3d4 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -1376,7 +1376,7 @@ datum var/list/all_items = owner.current.get_contents() for(var/obj/item/device/mmi/mmi in all_items) if(mmi.brainmob&&mmi.brainmob.mind==target) return 1 - for(var/obj/item/brain/brain in all_items) + for(var/obj/item/organ/brain/brain in all_items) if(brain.brainmob&&brain.brainmob.mind==target) return 1 return 0 diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm new file mode 100644 index 00000000000..4ce50d404c5 --- /dev/null +++ b/code/game/machinery/bioprinter.dm @@ -0,0 +1,71 @@ +//These machines are mostly just here for debugging/spawning. Skeletons of the feature to come. + +/obj/machinery/bioprinter + name = "bioprinter" + desc = "It's a machine that grows replacement organs." + icon = 'icons/obj/surgery.dmi' + + icon_state = "bioprinter" + + var/prints_prosthetics + var/stored_matter = 200 + var/loaded_dna //Blood sample for DNA hashing. + var/list/products = list( + "heart" = list(/obj/item/organ/heart, 50), + "lungs" = list(/obj/item/organ/lungs, 40), + "kidneys" = list(/obj/item/organ/kidneys,20), + "eyes" = list(/obj/item/organ/eyes, 30), + "liver" = list(/obj/item/organ/liver, 50) + ) + +/obj/machinery/bioprinter/prosthetics + name = "prosthetics fabricator" + desc = "It's a machine that prints prosthetic organs." + prints_prosthetics = 1 + +/obj/machinery/bioprinter/attack_hand(mob/user) + + var/choice = input("What would you like to print?") as null|anything in products + if(!choice) + return + + if(stored_matter >= products[choice][2]) + + stored_matter -= products[choice][2] + var/new_organ = products[choice][1] + var/obj/item/organ/O = new new_organ(get_turf(src)) + + if(prints_prosthetics) + O.robotic = 2 + else if(loaded_dna) + visible_message("The printer would be using the DNA sample if it was coded.") + //TODO: Copy DNA hash or donor reference over to new organ. + + visible_message("The bioprinter spits out a new organ.") + + else + user << "There is not enough matter in the printer." + +/obj/machinery/bioprinter/attackby(obj/item/weapon/W, mob/user) + + // DNA sample from syringe. + if(!prints_prosthetics && istype(W,/obj/item/weapon/reagent_containers/syringe)) + user << "You inject the blood sample into the bioprinter, but it isn't coded yet." + return + // Meat for biomass. + else if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) + user << "\blue \The [src] processes \the [W]." + stored_matter += 50 + user.drop_item() + del(W) + return + // Steel for matter. + else if(prints_prosthetics && istype(W, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = W + user << "\blue \The [src] processes \the [W]." + stored_matter += M.amount * 10 + user.drop_item() + del(W) + return + else + return..() \ No newline at end of file diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 1762225088a..ce76680b0d9 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -803,10 +803,7 @@ H.apply_damage(0.5*damage, BRUTE, "l_arm") H.apply_damage(0.5*damage, BRUTE, "r_arm") - var/obj/effect/decal/cleanable/blood/B = new(src.loc) - B.blood_DNA = list() - B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type - + blood_splatter(src,H,1) bloodiness += 4 // player on mulebot attempted to move diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 5e1fbbe50da..04f5efa5185 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -72,12 +72,12 @@ return var/mob/selected = null - for(var/mob/M in player_list) + for(var/mob/living/M in player_list) //Dead people only thanks! if ((M.stat != 2) || (!M.client)) continue //They need a brain! - if ((istype(M, /mob/living/carbon/human)) && (M:brain_op_stage >= 4.0)) + if ((istype(M, /mob/living/carbon/human)) && (!M.has_brain())) continue if (M.ckey == find_key) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 9ce8ccb4fc6..47eb7ca5583 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -337,7 +337,7 @@ if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna)) scantemp = "Error: Unable to locate valid genetic data." return - if (subject.brain_op_stage == 4.0) + if (!subject.has_brain()) scantemp = "Error: No signs of intelligence detected." return if (subject.suiciding == 1) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index cf05308e400..345d9f44d5d 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -81,7 +81,7 @@ if (istype(O, /mob/living/carbon/human)) var/mob/living/carbon/human/H = O var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] - if ((E.damage > E.min_bruised_damage && prob(E.damage + 50))) + if (E && (E.damage > E.min_bruised_damage && prob(E.damage + 50))) flick("e_flash", O:flash) E.damage += rand(1, 5) else diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 6e1cc86633c..b4155d6fcae 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -53,7 +53,7 @@ Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called. */ var/list/sprite_sheets_obj = null - + /obj/item/device icon = 'icons/obj/device.dmi' @@ -516,8 +516,8 @@ user << "\red You're going to need to remove the eye covering first." return - if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N slimes also don't have eyes! - user << "\red You cannot locate any eyes on this creature!" + if(!M.has_eyes()) + user << "\red You cannot locate any eyes on [M]!" return user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" @@ -533,20 +533,22 @@ M.weakened += 4 M.adjustBruteLoss(10) */ - if(M != user) - for(var/mob/O in (viewers(M) - user - M)) - O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1) - M << "\red [user] stabs you in the eye with [src]!" - user << "\red You stab [M] in the eye with [src]!" - else - user.visible_message( \ - "\red [user] has stabbed themself with [src]!", \ - "\red You stab yourself in the eyes with [src]!" \ - ) + if(istype(M, /mob/living/carbon/human)) + var/datum/organ/internal/eyes/eyes = H.internal_organs_by_name["eyes"] - if(!eyes) - return + + if(M != user) + for(var/mob/O in (viewers(M) - user - M)) + O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1) + M << "\red [user] stabs you in the eye with [src]!" + user << "\red You stab [M] in the eye with [src]!" + else + user.visible_message( \ + "\red [user] has stabbed themself with [src]!", \ + "\red You stab yourself in the eyes with [src]!" \ + ) + eyes.damage += rand(3,4) if(eyes.damage >= eyes.min_bruised_damage) if(M.stat != 2) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index d3149ab90f8..aa7e260371b 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -173,7 +173,7 @@ REAGENT SCANNER // user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.") if (M.has_brain_worms()) user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") - else if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && M:brain_op_stage == 4.0) + else if (M.getBrainLoss() >= 100 || !M.has_brain()) user.show_message("\red Subject is brain dead.") else if (M.getBrainLoss() >= 60) user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.") diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index dd60f16645a..f5ad4fa9fde 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -20,7 +20,7 @@ var/damage = round(30/(get_dist(B,get_turf(src))+1)) B.health -= damage B.update_icon() - + new/obj/effect/effect/smoke/flashbang(src.loc) del(src) return @@ -84,7 +84,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] - if (E.damage >= E.min_bruised_damage) + if (E && E.damage >= E.min_bruised_damage) M << "\red Your eyes start to burn badly!" if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) if (E.damage >= E.min_broken_damage) diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index ddadcfddd8c..3080c05f09e 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -773,7 +773,7 @@ LOOK FOR SURGERY.DM*/ log_attack("[user.name] ([user.ckey]) debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") - var/obj/item/brain/B = new(M.loc) + var/obj/item/organ/brain/B = new(M.loc) B.transfer_identity(M) M:brain_op_stage = 4.0 diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index f4400132e80..fdb6a93b2e4 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -357,6 +357,8 @@ if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] + if(!E) + return if(H.species.flags & IS_SYNTHETIC) return switch(safety) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 19223c48f1c..42a63f26e58 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -153,50 +153,16 @@ B.virus2 = virus_copylist(M.virus2) return 1 //we bloodied the floor - - - //if there isn't a blood decal already, make one. - var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(src) - - //Species-specific blood. - if(M.species) - newblood.basecolor = M.species.blood_color - else - newblood.basecolor = "#A10808" - - newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type - newblood.virus2 = virus_copylist(M.virus2) - newblood.update_icon() - + blood_splatter(src,M.get_blood(M.vessel),1) return 1 //we bloodied the floor // Only adds blood on the floor -- Skie /turf/simulated/proc/add_blood_floor(mob/living/carbon/M as mob) if(istype(M, /mob/living/carbon/monkey)) - - var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(src) - this.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type - this.basecolor = "#A10808" - this.update_icon() - - else if(istype(M,/mob/living/carbon/human)) - - var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(src) - var/mob/living/carbon/human/H = M - - //Species-specific blood. - if(H.species) - this.basecolor = H.species.blood_color - else - this.basecolor = "#A10808" - this.update_icon() - - this.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type - + blood_splatter(src,M,1) else if( istype(M, /mob/living/carbon/alien )) var/obj/effect/decal/cleanable/blood/xeno/this = new /obj/effect/decal/cleanable/blood/xeno(src) this.blood_DNA["UNKNOWN BLOOD"] = "X*" - else if( istype(M, /mob/living/silicon/robot )) new /obj/effect/decal/cleanable/blood/oil(src) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 95183949160..fdd28f5bccb 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -135,7 +135,7 @@ I said no! /datum/recipe/brainburger items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/brain + /obj/item/organ/brain ) result = /obj/item/weapon/reagent_containers/food/snacks/brainburger @@ -1063,7 +1063,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/brain + /obj/item/organ/brain ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 23d5416fcae..214c091c3e8 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -202,6 +202,9 @@ Des: Removes all infected images from the alien. del(I) return +/mob/living/carbon/alien/has_eyes() + return 0 + #undef HEAT_DAMAGE_LEVEL_1 #undef HEAT_DAMAGE_LEVEL_2 #undef HEAT_DAMAGE_LEVEL_3 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index 2b084ce8b5c..6b7752f8137 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -27,7 +27,7 @@ // Queen check var/no_queen = 1 for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list) - if(!Q.key && Q.brain_op_stage != 4) + if(!Q.key && Q.has_brain()) continue no_queen = 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index defcc968d13..f1910fcfe30 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -304,7 +304,7 @@ blinded = 1 silent = 0 else //ALIVE. LIGHTS ARE ON - if(health < config.health_threshold_dead || brain_op_stage == 4.0) + if(health < config.health_threshold_dead || !has_brain()) death() blinded = 1 stat = DEAD diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 9bb6ae43767..97abbdec382 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -222,7 +222,7 @@ FUCK YOU MORE FAT CODE -Hawk*/ blinded = 1 silent = 0 else //ALIVE. LIGHTS ARE ON - if(health < -25 || brain_op_stage == 4.0) + if(health < -25 || !has_brain()) death() blinded = 1 silent = 0 diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 6959828f9b5..ae2ed011925 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -22,7 +22,7 @@ var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm. attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O,/obj/item/brain) && !brainmob) //Time to stick a brain in it --NEO + if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO if(!O:brainmob) user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain." return @@ -61,6 +61,7 @@ return ..() + //TODO: ORGAN REMOVAL UPDATE. Make the brain remain in the MMI so it doesn't lose organ data. attack_self(mob/user as mob) if(!brainmob) user << "\red You upend the MMI, but there's nothing in it." @@ -68,7 +69,7 @@ user << "\red You upend the MMI, but the brain is clamped into place." else user << "\blue You upend the MMI, spilling the brain onto the floor." - var/obj/item/brain/brain = new(user.loc) + var/obj/item/organ/brain/brain = new(user.loc) brainmob.container = null//Reset brainmob mmi var. brainmob.loc = brain//Throw mob into brain. living_mob_list -= brainmob//Get outta here diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 27b9da88e88..d2ba4fbb949 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,7 +1,7 @@ -/obj/item/brain +/obj/item/organ/brain name = "brain" - desc = "A piece of juicy meat found in a persons head." - icon = 'icons/obj/surgery.dmi' + health = 400 //They need to live awhile longer than other organs. + desc = "A piece of juicy meat found in a person's head." icon_state = "brain2" flags = TABLEPASS force = 1.0 @@ -11,32 +11,32 @@ throw_range = 5 origin_tech = "biotech=3" attack_verb = list("attacked", "slapped", "whacked") + prosthetic_name = "cyberbrain" + prosthetic_icon = "brain-prosthetic" + organ_tag = "brain" var/mob/living/carbon/brain/brainmob = null - New() - ..() - //Shifting the brain "mob" over to the brain object so it's easier to keep track of. --NEO - //WASSSSSUUUPPPP /N - spawn(5) - if(brainmob && brainmob.client) - brainmob.client.screen.len = null //clear the hud +/obj/item/organ/brain/New() + ..() + spawn(5) + if(brainmob && brainmob.client) + brainmob.client.screen.len = null //clear the hud - proc - transfer_identity(var/mob/living/carbon/H) - name = "[H]'s brain" - brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - brainmob.timeofhostdeath = H.timeofdeath - if(H.mind) - H.mind.transfer_to(brainmob) +/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H) + name = "[H]'s brain" + brainmob = new(src) + brainmob.name = H.real_name + brainmob.real_name = H.real_name + brainmob.dna = H.dna.Clone() + brainmob.timeofhostdeath = H.timeofdeath + if(H.mind) + H.mind.transfer_to(brainmob) - brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain." - callHook("debrain", list(brainmob)) + brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain." + callHook("debrain", list(brainmob)) -/obj/item/brain/examine() // -- TLE +/obj/item/organ/brain/examine() // -- TLE set src in oview(12) if (!( usr )) return @@ -47,53 +47,27 @@ else usr << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.." -/obj/item/brain/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(!istype(M, /mob)) - return +/obj/item/organ/brain/removed(var/mob/living/target,var/mob/living/user) - add_fingerprint(user) + ..() - if(!(user.zone_sel.selecting == ("head")) || !istype(M, /mob/living/carbon/human)) - return ..() + var/mob/living/simple_animal/borer/borer = target.has_brain_worms() - if( !(locate(/obj/machinery/optable, M.loc) && M.resting) && ( !(locate(/obj/structure/table/, M.loc) && M.lying) && prob(50) ) ) - return ..() + if(borer) + borer.detatch() //Should remove borer if the brain is removed - RR - var/mob/living/carbon/human/H = M - if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) - // you can't stab someone in the eyes wearing a mask! - user << "\blue You're going to need to remove their head cover first." - return + var/mob/living/carbon/human/H = target + var/obj/item/organ/brain/B = src + if(istype(B) && istype(H)) + B.transfer_identity(target) -//since these people will be dead M != usr +/obj/item/organ/brain/replaced(var/mob/living/target) - if(M:brain_op_stage == 4.0) - for(var/mob/O in viewers(M, null)) - if(O == (user || M)) - continue - if(M == user) - O.show_message(text("\red [user] inserts [src] into his head!"), 1) - else - O.show_message(text("\red [M] has [src] inserted into his head by [user]."), 1) - - if(M != user) - M << "\red [user] inserts [src] into your head!" - user << "\red You insert [src] into [M]'s head!" - else - user << "\red You insert [src] into your head!" - - //this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO - if(M.key)//Revised. /N - M.ghostize() + if(target.key) + target.ghostize() + if(brainmob) if(brainmob.mind) - brainmob.mind.transfer_to(M) + brainmob.mind.transfer_to(target) else - M.key = brainmob.key - - M:brain_op_stage = 3.0 - - del(src) - else - ..() - return + target.key = brainmob.key \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index 62916d818da..897b03c8a14 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -36,7 +36,7 @@ if(container && istype(container, /obj/item/device/mmi)) del(container)//Gets rid of the MMI if there is one if(loc) - if(istype(loc,/obj/item/brain)) + if(istype(loc,/obj/item/organ/brain)) del(loc)//Gets rid of the brain item spawn(15) if(animation) del(animation) diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index 6877ed4b854..5ee424bd8db 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -10,7 +10,6 @@ construction_time = 75 var/searching = 0 var/askDelay = 10 * 60 * 1 - mob/living/carbon/brain/brainmob = null req_access = list(access_robotics) locked = 0 mecha = null//This does not appear to be used outside of reference in mecha.dm. @@ -136,7 +135,6 @@ src.brainmob.robot_talk_understand = 1 src.brainmob.stat = 0 src.brainmob.silent = 0 - src.brainmob.brain_op_stage = 4.0 dead_mob_list -= src.brainmob ..() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 0dff048d004..feed242bef0 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -1,7 +1,6 @@ /mob/living/carbon/ gender = MALE var/list/stomach_contents = list() - var/brain_op_stage = 0.0 var/list/datum/disease2/disease/virus2 = list() var/antibodies = 0 var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 2a9850171e7..c672950a18b 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -240,10 +240,11 @@ if(getBrainLoss() >= 60) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if(!key && brain_op_stage != 4 && stat != DEAD) - msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n" - else if(!client && brain_op_stage != 4 && stat != DEAD) - msg += "[t_He] [t_has] suddenly fallen asleep.\n" + if(has_brain() && stat != DEAD) + if(!key) + msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n" + else if(!client) + msg += "[t_He] [t_has] suddenly fallen asleep.\n" var/list/wound_flavor_text = list() var/list/is_destroyed = list() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b250884e9f7..3f7faeac8e6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -535,13 +535,13 @@ //Now checks siemens_coefficient of the affected area by default /mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null) if(status_flags & GODMODE) return 0 //godmode - + if (!def_zone) def_zone = pick("l_hand", "r_hand") - + var/datum/organ/external/affected_organ = get_organ(check_zone(def_zone)) var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ) - + return ..(shock_damage, source, siemens_coeff, def_zone) @@ -1135,12 +1135,12 @@ /mob/living/carbon/human/proc/is_lung_ruptured() var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] - return L.is_bruised() + return L && L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] - if(!L.is_bruised()) + if(L && !L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) L.damage = L.min_bruised_damage @@ -1300,6 +1300,7 @@ spawn(0) update_icons() + fixblood() if(species) return 1 @@ -1567,3 +1568,17 @@ flavor_text += flavor_texts[T] flavor_text += "\n\n" return ..() + +/mob/living/carbon/human/has_brain() + if(internal_organs_by_name["brain"]) + var/datum/organ/internal/brain = internal_organs_by_name["brain"] + if(brain && istype(brain)) + return 1 + return 0 + +/mob/living/carbon/human/has_eyes() + if(internal_organs_by_name["eyes"]) + var/datum/organ/internal/eyes = internal_organs_by_name["eyes"] + if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY) + return 1 + return 0 diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 01caff57e5a..8b4e010d4b5 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -17,13 +17,19 @@ /mob/living/carbon/human/getBrainLoss() var/res = brainloss - var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] - if (sponge.is_bruised()) - res += 20 - if (sponge.is_broken()) - res += 50 - res = min(res,maxHealth*2) - return res + if(species && species.has_organ["brain"]) + var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] + if(!sponge) + res += 200 + else + if (sponge.is_bruised()) + res += 20 + if (sponge.is_broken()) + res += 50 + + res = min(res,maxHealth*2) + return res + return 0 //These procs fetch a cumulative total damage from all organs /mob/living/carbon/human/getBruteLoss() @@ -264,20 +270,20 @@ This function restores all organs. /mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null) //visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]") - + //Handle other types of damage if((damagetype != BRUTE) && (damagetype != BURN)) if(damagetype == HALLOSS) if ((damage > 25 && prob(20)) || (damage > 50 && prob(60))) emote("scream") - - + + ..(damage, damagetype, def_zone, blocked) return 1 //Handle BRUTE and BURN damage handle_suit_punctures(damagetype, damage) - + if(blocked >= 2) return 0 var/datum/organ/external/organ = null diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index c5fb663116a..dd02d3c17d7 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -95,6 +95,9 @@ //Disabilities handle_disabilities() + //Organ failure. + handle_organs() + //Random events (vomiting etc) handle_random_events() @@ -1081,7 +1084,7 @@ handle_organs() //Optimized. handle_blood() - if(health <= config.health_threshold_dead || brain_op_stage == 4.0) + if(health <= config.health_threshold_dead || !has_brain()) death() blinded = 1 silent = 0 @@ -1160,15 +1163,23 @@ //Eyes - if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own - blinded = 1 - else if(eye_blind) //blindness, heals slowly over time - eye_blind = max(eye_blind-1,0) - blinded = 1 + if(!species.has_organ["eyes"]) // Presumably if a species has no eyes, they see via something else. + eye_blind = 0 + blinded = 0 + eye_blurry = 0 + else if(!has_eyes()) // Eyes cut out? Permablind. + eye_blind = 1 + blinded = 1 + eye_blurry = 1 + else if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own + blinded = 1 + else if(eye_blind) // Blindness, heals slowly over time + eye_blind = max(eye_blind-1,0) + blinded = 1 else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster eye_blurry = max(eye_blurry-3, 0) - blinded = 1 - else if(eye_blurry) //blurry eyes heal slowly + blinded = 1 + else if(eye_blurry) // Blurry eyes heal slowly eye_blurry = max(eye_blurry-1, 0) //Ears diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 67f0b904ed4..85fdb33a8da 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -51,6 +51,8 @@ var/coretype = /obj/item/slime_extract/grey var/list/slime_mutation[4] + var/core_removal_stage = 0 //For removing cores. + /mob/living/carbon/slime/New() create_reagents(100) spawn (0) @@ -984,6 +986,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 if(A) G << "Golem rune created in [A.name]." +/mob/living/carbon/slime/has_eyes() + return 0 + //////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them//////////////////////// /* diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index ce681063582..44a7e7a2593 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -485,7 +485,7 @@ silent = 0 else //ALIVE. LIGHTS ARE ON updatehealth() - if(health < config.health_threshold_dead || brain_op_stage == 4.0) + if(health < config.health_threshold_dead || !has_brain()) death() blinded = 1 stat = DEAD diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 286bffb3a0f..d5e8a167614 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -54,6 +54,15 @@ var/race_key = 0 var/icon/icon_template + var/list/has_organ = list( + "heart" = /datum/organ/internal/heart, + "lungs" = /datum/organ/internal/lungs, + "liver" = /datum/organ/internal/liver, + "kidneys" = /datum/organ/internal/kidney, + "brain" = /datum/organ/internal/brain, + "appendix" = /datum/organ/internal/appendix, + "eyes" = /datum/organ/internal/eyes + ) /datum/species/New() unarmed = new unarmed_type() @@ -73,12 +82,9 @@ H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"]) H.internal_organs = list() - H.internal_organs_by_name["heart"] = new/datum/organ/internal/heart(H) - H.internal_organs_by_name["lungs"] = new/datum/organ/internal/lungs(H) - H.internal_organs_by_name["liver"] = new/datum/organ/internal/liver(H) - H.internal_organs_by_name["kidney"] = new/datum/organ/internal/kidney(H) - H.internal_organs_by_name["brain"] = new/datum/organ/internal/brain(H) - H.internal_organs_by_name["eyes"] = new/datum/organ/internal/eyes(H) + for(var/organ in has_organ) + var/organ_type = has_organ[organ] + H.internal_organs_by_name[organ] = new organ_type(H) for(var/name in H.organs_by_name) H.organs += H.organs_by_name[name] diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index daf0e370049..a4e5e0586fd 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -784,3 +784,9 @@ var/area/new_area = get_area(loc) if(new_area) new_area.Entered(src) + +/mob/living/proc/has_brain() + return 1 + +/mob/living/proc/has_eyes() + return 1 \ No newline at end of file diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 3a691d9d353..38feee53e28 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -30,8 +30,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 /mob/living/carbon/human/proc/fixblood() for(var/datum/reagent/blood/B in vessel.reagent_list) if(B.id == "blood") - B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \ + B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.blood_color,"blood_type"=dna.b_type, \ "resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = null) + B.color = B.data["blood_color"] // Takes care blood loss and regeneration /mob/living/carbon/human/proc/handle_blood() @@ -63,14 +64,17 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Damaged heart virtually reduces the blood volume, as the blood isn't // being pumped properly anymore. - var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"] + if(species && species.has_organ["heart"]) + var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"] - if(heart.damage > 1 && heart.damage < heart.min_bruised_damage) - blood_volume *= 0.8 - else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage) - blood_volume *= 0.6 - else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY) - blood_volume *= 0.3 + if(!heart) + blood_volume = 0 + else if(heart.damage > 1 && heart.damage < heart.min_bruised_damage) + blood_volume *= 0.8 + else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage) + blood_volume *= 0.6 + else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY) + blood_volume *= 0.3 //Effects of bloodloss switch(blood_volume) @@ -141,31 +145,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 if(!amt) return - var/turf/T = get_turf(src) - var/list/obj/effect/decal/cleanable/blood/drip/nums = list() - var/list/iconL = list("1","2","3","4","5") - vessel.remove_reagent("blood",amt) - - for(var/obj/effect/decal/cleanable/blood/drip/G in T) - nums += G - iconL.Remove(G.icon_state) - - if (nums.len < 5) - var/obj/effect/decal/cleanable/blood/drip/this = new(T) - this.icon_state = pick(iconL) - this.blood_DNA = list() - this.blood_DNA[dna.unique_enzymes] = dna.b_type - for (var/ID in virus2) - var/datum/disease2/disease/V = virus2[ID] - this.virus2[ID] = V.getcopy() - if (species) this.basecolor = species.blood_color - this.update_icon() - - else - for(var/obj/effect/decal/cleanable/blood/drip/G in nums) - del G - T.add_blood(src) + blood_splatter(src,src) /**************************************************** BLOOD TRANSFERS @@ -193,6 +174,12 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 B.data["resistances"] = src.resistances.Copy() B.data["blood_type"] = copytext(src.dna.b_type,1,0) + // Putting this here due to return shenanigans. + if(istype(src,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + B.data["blood_colour"] = H.species.blood_color + B.color = B.data["blood_colour"] + var/list/temp_chem = list() for(var/datum/reagent/R in src.reagents.reagent_list) temp_chem += R.id @@ -279,4 +266,71 @@ proc/blood_incompatible(donor,receiver) if("O") if(donor_antigen != "O") return 1 //AB is a universal receiver. - return 0 \ No newline at end of file + return 0 + +proc/blood_splatter(var/target,var/datum/reagent/blood/source,var/large) + + var/obj/effect/decal/cleanable/blood/B + var/decal_type = /obj/effect/decal/cleanable/blood/splatter + var/turf/T = get_turf(target) + + if(istype(source,/mob/living/carbon/human)) + var/mob/living/carbon/human/M = source + source = M.get_blood(M.vessel) + else if(istype(source,/mob/living/carbon/monkey)) + var/mob/living/carbon/monkey/donor = source + if(donor.dna) + source = new() + source.data["blood_DNA"] = donor.dna.unique_enzymes + source.data["blood_type"] = donor.dna.b_type + + // Are we dripping or splattering? + if(!large) + + // Only a certain number of drips can be on a given turf. + var/list/drips = list() + var/list/drip_icons = list("1","2","3","4","5") + + for(var/obj/effect/decal/cleanable/blood/drip/drop in T) + drips += drop + drip_icons.Remove(drop.icon_state) + + // If we have too many drips, remove them and spawn a proper blood splatter. + if(drips.len >= 5) + //TODO: copy all virus data from drips to new splatter? + for(var/obj/effect/decal/cleanable/blood/drip/drop in drips) + del drop + else + decal_type = /obj/effect/decal/cleanable/blood/drip + + // Find a blood decal or create a new one. + B = locate(decal_type) in T + if(!B) + B = new decal_type(T) + + // If there's no data to copy, call it quits here. + if(!source) + return B + + // Update appearance. + if(source.data["blood_colour"]) + B.basecolor = source.data["blood_colour"] + B.update_icon() + + // Update blood information. + if(source.data["blood_DNA"]) + B.blood_DNA = list() + if(source.data["blood_type"]) + B.blood_DNA[source.data["blood_DNA"]] = source.data["blood_type"] + else + B.blood_DNA[source.data["blood_DNA"]] = "O+" + + // Update virus information. //Looks like this is out of date. + //for(var/datum/disease/D in source.data["viruses"]) + // var/datum/disease/new_virus = D.Copy(1) + // source.viruses += new_virus + // new_virus.holder = B + if(source.data["virus2"]) + B.virus2 = virus_copylist(source.data["virus2"]) + + return B \ No newline at end of file diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index f0c28d87c3b..12b180fd546 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -1,6 +1,8 @@ /datum/organ var/name = "organ" var/mob/living/carbon/human/owner = null + var/status = 0 + var/vital //Lose a vital limb, die immediately. var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, @@ -56,6 +58,7 @@ // Takes care of organ related updates, such as broken and missing limbs /mob/living/carbon/human/proc/handle_organs() + number_wounds = 0 var/leg_tally = 2 var/force_process = 0 @@ -72,6 +75,19 @@ for(var/datum/organ/internal/I in internal_organs) I.process() + // Also handles some internal organ processing when the organs are missing completely. + // Only handles missing liver and kidneys for now. + // This is a bit harsh, but really if you're missing an entire bodily organ you're in deep shit. + if(species.has_organ["liver"]) + var/datum/organ/internal/liver = internal_organs_by_name["liver"] + if(!liver || liver.status & ORGAN_CUT_AWAY) + reagents.add_reagent("toxin", rand(1,3)) + + if(species.has_organ["kidneys"]) + var/datum/organ/internal/kidney = internal_organs_by_name["kidneys"] + if(!kidney || kidney.status & ORGAN_CUT_AWAY) + reagents.add_reagent("toxin", rand(1,3)) + if(!force_process && !bad_external_organs.len) return diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 79bbe771b30..c4df67cc870 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -32,12 +32,11 @@ var/damage_msg = "\red You feel an intense pain" var/broken_description - var/vital //Lose a vital limb, die immediately. - var/status = 0 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/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. var/obj/item/hidden = null var/list/implants = list() @@ -855,6 +854,7 @@ Note that amputating the affected organ does in fact remove the infection from t min_broken_damage = 40 body_part = UPPER_TORSO vital = 1 + encased = "ribcage" /datum/organ/external/groin name = "groin" @@ -958,6 +958,7 @@ Note that amputating the affected organ does in fact remove the infection from t body_part = HEAD var/disfigured = 0 vital = 1 + encased = "skull" /datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon) if (!owner) @@ -1062,6 +1063,7 @@ obj/item/weapon/organ/r_hand obj/item/weapon/organ/r_leg name = "right leg" icon_state = "r_leg" + obj/item/weapon/organ/head name = "head" icon_state = "head_m" @@ -1158,11 +1160,12 @@ obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob) 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/posibrain/B = new(loc) B.transfer_identity(brainmob) else - var/obj/item/brain/B = new(loc) + var/obj/item/organ/brain/B = new(loc) B.transfer_identity(brainmob) brain_op_stage = 4.0 diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 4ed10047564..e8c7acbfbf0 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -10,6 +10,9 @@ var/min_broken_damage = 30 var/parent_organ = "chest" var/robotic = 0 //For being a robot + var/removed_type //When removed, forms this object. + var/list/transplant_data // Blood DNA and colour of donor + var/rejecting // Is this organ already being rejected? /datum/organ/internal/proc/rejuvenate() damage=0 @@ -20,20 +23,19 @@ /datum/organ/internal/proc/is_broken() return damage >= min_broken_damage - - /datum/organ/internal/New(mob/living/carbon/human/H) ..() - var/datum/organ/external/E = H.organs_by_name[src.parent_organ] - if(E.internal_organs == null) - E.internal_organs = list() - E.internal_organs |= src - H.internal_organs |= src - src.owner = H + if(H) + var/datum/organ/external/E = H.organs_by_name[src.parent_organ] + if(E.internal_organs == null) + E.internal_organs = list() + E.internal_organs |= src + H.internal_organs |= src + src.owner = H /datum/organ/internal/process() - //Process infections + //Process infections if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT)) //TODO make robotic internal and external organs separate types of organ instead of a flag germ_level = 0 return @@ -44,10 +46,10 @@ //** Handle the effects of infections var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - + if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) germ_level-- - + if (germ_level >= INFECTION_LEVEL_ONE/2) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes if(antibiotics < 5 && prob(round(germ_level/6))) @@ -58,10 +60,33 @@ //spread germs if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) parent.germ_level++ - + if (prob(3)) //about once every 30 seconds take_damage(1,silent=prob(30)) + // Process unsuitable transplants. TODO: consider some kind of + // immunosuppressant that changes transplant data to make it match. + if(transplant_data) + if(!rejecting) //Should this transplant reject? + if(owner.species != transplant_data["species"]) //Nope. + rejecting = 1 + else if(prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type)) + rejecting = 1 + else + rejecting++ //Rejection severity increases over time. + if(rejecting % 10 == 0) //Only fire every ten rejection ticks. + switch(rejecting) + if(1 to 50) + take_damage(rand(1,2)) + if(51 to 200) + take_damage(rand(2,3)) + if(201 to 500) + take_damage(rand(3,4)) + owner.reagents.add_reagent("toxin", 1) + if(501 to INFINITY) + take_damage(5) + owner.reagents.add_reagent("toxin", rand(3,5)) + /datum/organ/internal/proc/take_damage(amount, var/silent=0) if(src.robotic == 2) src.damage += (amount * 0.8) @@ -111,21 +136,22 @@ INTERNAL ORGANS DEFINES ****************************************************/ -/datum/organ/internal/heart +/datum/organ/internal/heart // This is not set to vital because death immediately occurs in blood.dm if it is removed. name = "heart" parent_organ = "chest" - + removed_type = /obj/item/organ/heart /datum/organ/internal/lungs name = "lungs" parent_organ = "chest" + removed_type = /obj/item/organ/lungs process() ..() if (germ_level > INFECTION_LEVEL_ONE) if(prob(5)) owner.emote("cough") //respitory tract infection - + if(is_bruised()) if(prob(2)) spawn owner.emote("me", 1, "coughs up blood!") @@ -138,6 +164,7 @@ name = "liver" parent_organ = "chest" var/process_accuracy = 10 + removed_type = /obj/item/organ/liver process() ..() @@ -147,7 +174,7 @@ if (germ_level > INFECTION_LEVEL_TWO) if(prob(1)) spawn owner.vomit() - + if(owner.life_tick % process_accuracy == 0) if(src.damage < 0) src.damage = 0 @@ -178,16 +205,20 @@ owner.adjustToxLoss(0.3 * process_accuracy) /datum/organ/internal/kidney - name = "kidney" - parent_organ = "chest" + name = "kidneys" + parent_organ = "groin" + removed_type = /obj/item/organ/kidneys /datum/organ/internal/brain name = "brain" parent_organ = "head" + removed_type = /obj/item/organ/brain + vital = 1 /datum/organ/internal/eyes name = "eyes" parent_organ = "head" + removed_type = /obj/item/organ/eyes process() //Eye damage replaces the old eye_stat var. ..() @@ -195,3 +226,20 @@ owner.eye_blurry = 20 if(is_broken()) owner.eye_blind = 20 + +/datum/organ/internal/appendix + name = "appendix" + parent_organ = "groin" + removed_type = /obj/item/organ/appendix + +/datum/organ/internal/proc/remove(var/mob/user) + + if(!removed_type) return 0 + + var/obj/item/organ/removed_organ = new removed_type(get_turf(user)) + + if(istype(removed_organ)) + removed_organ.organ_data = src + removed_organ.update() + + return removed_organ \ No newline at end of file diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm new file mode 100644 index 00000000000..c48a9d4b541 --- /dev/null +++ b/code/modules/organs/organ_objects.dm @@ -0,0 +1,232 @@ +/obj/item/organ + name = "organ" + desc = "It looks like it probably just plopped out." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + + health = 100 // Process() ticks before death. + + var/fresh = 3 // Squirts of blood left in it. + var/dead_icon // Icon used when the organ dies. + var/robotic // Is the limb prosthetic? + var/organ_tag // What slot does it go in? + var/organ_type = /datum/organ/internal // Used to spawn the relevant organ data when produced via a machine or spawn(). + var/datum/organ/internal/organ_data // Stores info when removed. + var/prosthetic_name = "prosthetic organ" // Flavour string for robotic organ. + var/prosthetic_icon // Icon for robotic organ. + +/obj/item/organ/attack_self(mob/user as mob) + + // Convert it to an edible form, yum yum. + if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth") + bitten(user) + return + +/obj/item/organ/New() + ..() + create_reagents(5) + if(!robotic) + processing_objects += src + spawn(1) + update() + +/obj/item/organ/Del() + if(!robotic) processing_objects -= src + ..() + +/obj/item/organ/process() + + if(robotic) + processing_objects -= src + return + + // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? + if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) + return + + if(fresh && prob(40)) + fresh-- + var/datum/reagent/blood = reagents.reagent_list["blood"] + blood_splatter(src,blood,1) + + health -= rand(1,3) + if(health <= 0) + die() + +/obj/item/organ/proc/die() + name = "dead [initial(name)]" + if(dead_icon) icon_state = dead_icon + health = 0 + processing_objects -= src + //TODO: Grey out the icon state. + //TODO: Inject an organ with peridaxon to make it alive again. + +/obj/item/organ/proc/roboticize() + + robotic = (organ_data && organ_data.robotic) ? organ_data.robotic : 1 + + if(prosthetic_name) + name = prosthetic_name + + if(prosthetic_icon) + icon_state = prosthetic_icon + else + //TODO: convert to greyscale. + +/obj/item/organ/proc/update() + + if(!organ_data) + organ_data = new /datum/organ/internal() + + if(robotic) + organ_data.robotic = robotic + + if(organ_data.robotic >= 2) + roboticize() + +// Brain is defined in brain_item.dm. +/obj/item/organ/heart + name = "heart" + icon_state = "heart-on" + prosthetic_name = "circulatory pump" + prosthetic_icon = "heart-prosthetic" + organ_tag = "heart" + fresh = 6 // Juicy. + dead_icon = "heart-off" + +/obj/item/organ/lungs + name = "lungs" + icon_state = "lungs" + prosthetic_name = "gas exchange system" + prosthetic_icon = "lungs-prosthetic" + organ_tag = "lungs" + +/obj/item/organ/kidneys + name = "kidneys" + icon_state = "kidneys" + prosthetic_name = "prosthetic kidneys" + prosthetic_icon = "kidneys-prosthetic" + organ_tag = "kidneys" + +/obj/item/organ/eyes + name = "eyeballs" + icon_state = "eyes" + prosthetic_name = "visual prosthesis" + prosthetic_icon = "eyes-prosthetic" + organ_tag = "eyes" + + var/eye_colour + +/obj/item/organ/liver + name = "liver" + icon_state = "liver" + prosthetic_name = "toxin filter" + prosthetic_icon = "liver-prosthetic" + organ_tag = "liver" + +/obj/item/organ/appendix + name = "appendix" + icon_state = "appendix" + organ_tag = "appendix" + +//These are here so they can be printed out via the fabricator. +/obj/item/organ/heart/prosthetic + robotic = 2 + +/obj/item/organ/lungs/prosthetic + robotic = 2 + +/obj/item/organ/kidneys/prosthetic + robotic = 2 + +/obj/item/organ/eyes/prosthetic + robotic = 2 + +/obj/item/organ/liver/prosthetic + robotic = 2 + +/obj/item/organ/appendix + name = "appendix" + +/obj/item/organ/proc/removed(var/mob/living/target,var/mob/living/user) + + if(!target || !user) + return + + if(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)])" + msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (JMP)") + target.death() + +/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user) + + ..() + + var/inflamed = 0 + for(var/datum/disease/appendicitis/appendicitis in target.viruses) + inflamed = 1 + appendicitis.cure() + target.resistances += appendicitis + + if(inflamed) + icon_state = "appendixinflamed" + name = "inflamed appendix" + +/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user) + + if(!eye_colour) + eye_colour = list(0,0,0) + + ..() //Make sure target is set so we can steal their eye colour for later. + var/mob/living/carbon/human/H = target + if(istype(H)) + eye_colour = list( + H.r_eyes ? H.r_eyes : 0, + H.g_eyes ? H.g_eyes : 0, + H.b_eyes ? H.b_eyes : 0 + ) + + // Leave bloody red pits behind! + H.r_eyes = 128 + H.g_eyes = 0 + H.b_eyes = 0 + H.update_body() + +/obj/item/organ/proc/replaced(var/mob/living/target) + return + +/obj/item/organ/eyes/replaced(var/mob/living/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() + +/obj/item/organ/proc/bitten(mob/user) + + if(robotic) + return + + user << "\blue You take an experimental bite out of \the [src]." + var/datum/reagent/blood = reagents.reagent_list["blood"] + blood_splatter(src,blood,1) + + + user.drop_from_inventory(src) + var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src)) + O.name = name + O.icon_state = dead_icon ? dead_icon : icon_state + + // Pass over the blood. + reagents.trans_to(O, reagents.total_volume) + + if(fingerprints) O.fingerprints = fingerprints.Copy() + if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy() + if(fingerprintslast) O.fingerprintslast = fingerprintslast + + user.put_in_active_hand(O) + del(src) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index b1858cd6987..13962c71346 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -95,7 +95,7 @@ datum blood - data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null, "antibodies" = null) + data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"blood_colour"= "#A10808","resistances"=null,"trace_chem"=null, "antibodies" = null) name = "Blood" id = "blood" reagent_state = LIQUID @@ -128,49 +128,30 @@ datum var/mob/living/carbon/C = M C.antibodies |= self.data["antibodies"] + on_merge(var/data) + if(data["blood_colour"]) + color = data["blood_colour"] + return ..() - + on_update(var/atom/A) + if(data["blood_colour"]) + color = data["blood_colour"] + return ..() reaction_turf(var/turf/simulated/T, var/volume)//splash the blood all over the place if(!istype(T)) return var/datum/reagent/blood/self = src src = null if(!(volume >= 3)) return - //var/datum/disease/D = self.data["virus"] + if(!self.data["donor"] || istype(self.data["donor"], /mob/living/carbon/human)) - var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T //find some blood here - if(!blood_prop) //first blood! - blood_prop = new(T) - blood_prop.blood_DNA[self.data["blood_DNA"]] = self.data["blood_type"] - - for(var/datum/disease/D in self.data["viruses"]) - var/datum/disease/newVirus = D.Copy(1) - blood_prop.viruses += newVirus - newVirus.holder = blood_prop - - if(self.data["virus2"]) - blood_prop.virus2 = virus_copylist(self.data["virus2"]) - - + blood_splatter(T,self,1) else if(istype(self.data["donor"], /mob/living/carbon/monkey)) - var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T - if(!blood_prop) - blood_prop = new(T) - blood_prop.blood_DNA["Non-Human DNA"] = "A+" - for(var/datum/disease/D in self.data["viruses"]) - var/datum/disease/newVirus = D.Copy(1) - blood_prop.viruses += newVirus - newVirus.holder = blood_prop - + var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1) + if(B) B.blood_DNA["Non-Human DNA"] = "A+" else if(istype(self.data["donor"], /mob/living/carbon/alien)) - var/obj/effect/decal/cleanable/blood/xeno/blood_prop = locate() in T - if(!blood_prop) - blood_prop = new(T) - blood_prop.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" - for(var/datum/disease/D in self.data["viruses"]) - var/datum/disease/newVirus = D.Copy(1) - blood_prop.viruses += newVirus - newVirus.holder = blood_prop + var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1) + if(B) B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" return /* Must check the transfering of reagents and their data first. They all can point to one disease datum. @@ -1276,7 +1257,7 @@ datum if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] - if(istype(E)) + if(E && istype(E)) if(E.damage > 0) E.damage = max(E.damage - 1, 0) ..() @@ -3024,7 +3005,9 @@ datum if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/liver/L = H.internal_organs_by_name["liver"] - if (istype(L)) + if (!L) + H.adjustToxLoss(5) + else if(istype(L)) L.take_damage(0.1, 1) H.adjustToxLoss(0.1) ..() @@ -3264,13 +3247,13 @@ datum if(prob(5)) if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"] - if (istype(L)) + if (L && istype(L)) L.take_damage(5, 0) if (300 to INFINITY) if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"] - if (istype(L)) + if (L && istype(L)) L.take_damage(100, 0) holder.remove_reagent(src.id, FOOD_METABOLISM) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 29001d9723f..28e369f531f 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -590,25 +590,20 @@ ..() reagents.add_reagent("nutriment", 1) -/obj/item/weapon/reagent_containers/food/snacks/appendix -//yes, this is the same as meat. I might do something different in future - name = "appendix" - desc = "An appendix which looks perfectly healthy." +/obj/item/weapon/reagent_containers/food/snacks/organ + + name = "organ" + desc = "It's good for you." icon = 'icons/obj/surgery.dmi' icon_state = "appendix" filling_color = "#E00D34" New() ..() - reagents.add_reagent("nutriment", 3) + reagents.add_reagent("nutriment", rand(3,5)) + reagents.add_reagent("toxin", rand(1,3)) src.bitesize = 3 -/obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed - name = "inflamed appendix" - desc = "An appendix which appears to be inflamed." - icon_state = "appendixinflamed" - filling_color = "#E00D7A" - /obj/item/weapon/reagent_containers/food/snacks/tofu name = "Tofu" icon_state = "tofu" @@ -1559,7 +1554,6 @@ On_Consume(var/mob/M) M << "Something inside of you suddently expands!" - if (istype(M, /mob/living/carbon/human)) //Do not try to understand. var/obj/item/weapon/surprise = new/obj/item/weapon(M) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 5e6277c8e7c..5617a3802e6 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -128,7 +128,7 @@ if(SYRINGE_INJECT) if(!reagents.total_volume) - user << "\red The Syringe is empty." + user << "\red The syringe is empty." return if(istype(target, /obj/item/weapon/implantcase/chem)) return diff --git a/code/modules/surgery/appendix.dm b/code/modules/surgery/appendix.dm deleted file mode 100644 index 91332eab06b..00000000000 --- a/code/modules/surgery/appendix.dm +++ /dev/null @@ -1,89 +0,0 @@ -//Procedures in this file: Appendectomy -////////////////////////////////////////////////////////////////// -// APPENDECTOMY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/appendectomy/ - priority = 2 - can_infect = 1 - blood_level = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - if (target_zone != "groin") - return 0 - var/datum/organ/external/groin = target.get_organ("groin") - if (!groin) - return 0 - if (groin.open < 2) - return 0 - return 1 - -/datum/surgery_step/appendectomy/cut_appendix - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/kitchenknife = 75, \ - /obj/item/weapon/shard = 50, \ - ) - - min_duration = 70 - max_duration = 90 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.appendix == 0 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts to separate [target]'s appendix from the abdominal wall with \the [tool].", \ - "You start to separate [target]'s appendix from the abdominal wall with \the [tool]." ) - target.custom_pain("The pain in your abdomen is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has separated [target]'s appendix with \the [tool]." , \ - "\blue You have separated [target]'s appendix with \the [tool].") - target.op_stage.appendix = 1 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/groin = target.get_organ("groin") - user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!", \ - "\red Your hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!") - groin.createwound(CUT, 50, 1) - -/datum/surgery_step/appendectomy/remove_appendix - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - - min_duration = 60 - max_duration = 80 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.appendix == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts removing [target]'s appendix with \the [tool].", \ - "You start removing [target]'s appendix with \the [tool].") - target.custom_pain("Someone's ripping out your bowels!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has removed [target]'s appendix with \the [tool].", \ - "\blue You have removed [target]'s appendix with \the [tool].") - var/app = 0 - for(var/datum/disease/appendicitis/appendicitis in target.viruses) - app = 1 - appendicitis.cure() - target.resistances += appendicitis - if (app) - new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(target)) - else - new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(target)) - target.op_stage.appendix = 2 - - 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) - user.visible_message("\red [user]'s hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!", \ - "\red Your hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!") - affected.createwound(BRUISE, 20) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 0bc14075677..605b1503d56 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -18,7 +18,7 @@ if (!hasorgans(target)) return 0 var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 2 && affected.stage == 0 + return affected.open >= 2 && affected.stage == 0 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) @@ -52,7 +52,7 @@ if (!hasorgans(target)) return 0 var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.name != "head" && affected.open == 2 && affected.stage == 1 + return affected.name != "head" && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) @@ -91,7 +91,7 @@ if (!hasorgans(target)) return 0 var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.name == "head" && affected.open == 2 && affected.stage == 1 + return affected.name == "head" && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \ @@ -127,7 +127,7 @@ if (!hasorgans(target)) return 0 var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 2 && affected.stage == 2 + return affected.open >= 2 && affected.stage == 2 begin_step(mob/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/braincore.dm b/code/modules/surgery/braincore.dm deleted file mode 100644 index 4bc804eab5d..00000000000 --- a/code/modules/surgery/braincore.dm +++ /dev/null @@ -1,279 +0,0 @@ -//Procedures in this file: Brain extraction. Brain fixing. Slime Core extraction. -////////////////////////////////////////////////////////////////// -// BRAIN SURGERY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/brain/ - priority = 2 - blood_level = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return target_zone == "head" && hasorgans(target) - -/datum/surgery_step/brain/saw_skull - allowed_tools = list( - /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 - ) - - min_duration = 50 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target_zone == "head" && target.brain_op_stage == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] begins to cut through [target]'s skull with \the [tool].", \ - "You begin to cut through [target]'s skull with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has cut [target]'s skull open with \the [tool].", \ - "\blue You have cut [target]'s skull open with \the [tool].") - target.brain_op_stage = 2 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, cracking [target]'s skull with \the [tool]!" , \ - "\red Your hand slips, cracking [target]'s skull with \the [tool]!" ) - target.apply_damage(max(10, tool.force), BRUTE, "head") - -/datum/surgery_step/brain/cut_brain - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/kitchenknife = 75, \ - /obj/item/weapon/shard = 50, \ - ) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts separating connections to [target]'s brain with \the [tool].", \ - "You start separating connections to [target]'s brain with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] separates connections to [target]'s brain with \the [tool].", \ - "\blue You separate connections to [target]'s brain with \the [tool].") - target.brain_op_stage = 3 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \ - "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!") - target.apply_damage(50, BRUTE, "head", 1, sharp=1) - -/datum/surgery_step/brain/saw_spine - allowed_tools = list( - /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 - ) - - min_duration = 50 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 3 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts separating [target]'s brain from \his spine with \the [tool].", \ - "You start separating [target]'s brain from spine with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] separates [target]'s brain from \his spine with \the [tool].", \ - "\blue You separate [target]'s brain from spine with \the [tool].") - - var/mob/living/simple_animal/borer/borer = target.has_brain_worms() - - if(borer) - borer.detatch() //Should remove borer if the brain is removed - RR - - user.attack_log += "\[[time_stamp()]\] Debrained [target.name] ([target.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)])" - target.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)])" - msg_admin_attack("[user.name] ([user.ckey]) debrained [target.name] ([target.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") - - var/mob/living/carbon/human/H - if(istype(target,/mob/living/carbon/human)) - H = target - - var/obj/item/brain/B - if(H && H.species && H.species.flags & IS_SYNTHETIC) - var/obj/item/device/mmi/posibrain/P = new(target.loc) - P.transfer_identity(target) - else - B = new(target.loc) - B.transfer_identity(target) - - target.internal_organs -= B - target.internal_organs_by_name -= "brain" - - target:brain_op_stage = 4.0 - target.death()//You want them to die after the brain was transferred, so not to trigger client death() twice. - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \ - "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!") - target.apply_damage(30, BRUTE, "head", 1, sharp=1) - if (ishuman(user)) - user:bloody_body(target) - user:bloody_hands(target, 0) - - -////////////////////////////////////////////////////////////////// -// BRAIN DAMAGE FIXING // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/brain/bone_chips - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts taking bone chips out of [target]'s brain with \the [tool].", \ - "You start taking bone chips out of [target]'s brain with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] takes out all the bone chips in [target]'s brain with \the [tool].", \ - "\blue You take out all the bone chips in [target]'s brain with \the [tool].") - target.brain_op_stage = 3 - - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \ - "\red Your hand slips, jabbing \the [tool] in [target]'s brain!") - target.apply_damage(30, BRUTE, "head", 1, sharp=1) - -/datum/surgery_step/brain/hematoma - allowed_tools = list( - /obj/item/weapon/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75 - ) - - min_duration = 90 - max_duration = 110 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 3 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts mending hematoma in [target]'s brain with \the [tool].", \ - "You start mending hematoma in [target]'s brain with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \ - "\blue You mend hematoma in [target]'s brain with \the [tool].") - var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] - if (sponge) - sponge.damage = 0 - - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \ - "\red Your hand slips, bruising [target]'s brain with \the [tool]!") - target.apply_damage(20, BRUTE, "head", 1, sharp=1) - -////////////////////////////////////////////////////////////////// -// SLIME CORE EXTRACTION // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/slime - is_valid_target(mob/living/carbon/slime/target) - return istype(target, /mob/living/carbon/slime/) - - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - return target.stat == 2 - -/datum/surgery_step/slime/cut_flesh - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/kitchenknife = 75, \ - /obj/item/weapon/shard = 50, \ - ) - - min_duration = 30 - max_duration = 50 - - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 0 - - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \ - "You start cutting through [target]'s flesh with \the [tool].") - - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] cuts through [target]'s flesh with \the [tool].", \ - "\blue You cut through [target]'s flesh with \the [tool], revealing its silky innards.") - target.brain_op_stage = 1 - - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ - "\red Your hand slips, tearing [target]'s flesh with \the [tool]!") - -/datum/surgery_step/slime/cut_innards - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/kitchenknife = 75, \ - /obj/item/weapon/shard = 50, \ - ) - - min_duration = 30 - max_duration = 50 - - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 1 - - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \ - "You start cutting [target]'s silky innards apart with \the [tool].") - - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ - "\blue You cut [target]'s innards apart with \the [tool], exposing the cores.") - target.brain_op_stage = 2 - - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ - "\red Your hand slips, tearing [target]'s innards with \the [tool]!") - -/datum/surgery_step/slime/saw_core - allowed_tools = list( - /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 - ) - - min_duration = 50 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - return ..() && target.brain_op_stage == 2 && target.cores > 0 - - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \ - "You start cutting out one of [target]'s cores with \the [tool].") - - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - target.cores-- - user.visible_message("\blue [user] cuts out one of [target]'s cores with \the [tool].",, \ - "\blue You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") - - if(target.cores >= 0) - new target.coretype(target.loc) - if(target.cores <= 0) - target.icon_state = "[target.colour] baby slime dead-nocore" - - - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, causing \him to miss the core!", \ - "\red Your hand slips, causing you to miss the core!") \ No newline at end of file diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm new file mode 100644 index 00000000000..85b5dd8dd3e --- /dev/null +++ b/code/modules/surgery/brainrepair.dm @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////// +// BRAIN DAMAGE FIXING // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/brain/bone_chips + allowed_tools = list( + /obj/item/weapon/hemostat = 100, \ + /obj/item/weapon/wirecutters = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 20 + ) + + priority = 3 + min_duration = 80 + max_duration = 100 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + return (sponge && sponge.damage > 0 && sponge.damage <= 20) && affected.open == 3 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] starts taking bone chips out of [target]'s brain with \the [tool].", \ + "You start taking bone chips out of [target]'s brain with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] takes out all the bone chips in [target]'s brain with \the [tool].", \ + "\blue You take out all the bone chips in [target]'s brain with \the [tool].") + var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + if (sponge) + sponge.damage = 0 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \ + "\red Your hand slips, jabbing \the [tool] in [target]'s brain!") + target.apply_damage(30, BRUTE, "head", 1, sharp=1) + +/datum/surgery_step/brain/hematoma + allowed_tools = list( + /obj/item/weapon/FixOVein = 100, \ + /obj/item/stack/cable_coil = 75 + ) + + priority = 3 + min_duration = 90 + max_duration = 110 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + return (sponge && sponge.damage > 20) && affected.open == 3 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] starts mending hematoma in [target]'s brain with \the [tool].", \ + "You start mending hematoma in [target]'s brain with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \ + "\blue You mend hematoma in [target]'s brain with \the [tool].") + var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + if (sponge) + sponge.damage = 20 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \ + "\red Your hand slips, bruising [target]'s brain with \the [tool]!") + target.apply_damage(20, BRUTE, "head", 1, sharp=1) \ No newline at end of file diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm new file mode 100644 index 00000000000..dcd6cc4b318 --- /dev/null +++ b/code/modules/surgery/encased.dm @@ -0,0 +1,220 @@ +//Procedures in this file: Generic ribcage opening steps, Removing alien embryo, Fixing internal organs. +////////////////////////////////////////////////////////////////// +// GENERIC RIBCAGE SURGERY // +////////////////////////////////////////////////////////////////// +/datum/surgery_step/open_encased + priority = 2 + can_infect = 1 + blood_level = 1 + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return 0 + + var/datum/organ/external/affected = target.get_organ(target_zone) + return affected.encased && affected.open >= 2 + + +/datum/surgery_step/open_encased/saw + allowed_tools = list( + /obj/item/weapon/circular_saw = 100, \ + /obj/item/weapon/hatchet = 75 + ) + + min_duration = 50 + max_duration = 70 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 2 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ + "You begin to cut through [target]'s [affected.encased] with \the [tool].") + target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("\blue [user] has cut [target]'s [affected.encased] open with \the [tool].", \ + "\blue You have cut [target]'s [affected.encased] open with \the [tool].") + affected.open = 2.5 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("\red [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!" , \ + "\red Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" ) + + affected.createwound(CUT, 20) + affected.fracture() + + +/datum/surgery_step/open_encased/retract + allowed_tools = list( + /obj/item/weapon/retractor = 100, \ + /obj/item/weapon/crowbar = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 20 + ) + + min_duration = 30 + max_duration = 40 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 2.5 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.display_name] with \the [tool]." + var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.display_name] with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "\blue [user] forces open [target]'s [affected.encased] with \the [tool]." + var/self_msg = "\blue You force open [target]'s [affected.encased] with \the [tool]." + user.visible_message(msg, self_msg) + + affected.open = 3 + + // Whoops! + if(prob(10)) + affected.fracture() + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "\red [user]'s hand slips, cracking [target]'s [affected.encased]!" + var/self_msg = "\red Your hand slips, cracking [target]'s [affected.encased]!" + user.visible_message(msg, self_msg) + + affected.createwound(BRUISE, 20) + affected.fracture() + +/datum/surgery_step/open_encased/close + allowed_tools = list( + /obj/item/weapon/retractor = 100, \ + /obj/item/weapon/crowbar = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 20 + ) + + min_duration = 20 + max_duration = 40 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 3 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "\blue [user] bends [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = "\blue You bend [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) + + affected.open = 2.5 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "\red [user]'s hand slips, bending [target]'s [affected.encased] the wrong way!" + var/self_msg = "\red Your hand slips, bending [target]'s [affected.encased] the wrong way!" + user.visible_message(msg, self_msg) + + affected.createwound(BRUISE, 20) + affected.fracture() + + /*if (prob(40)) //TODO: ORGAN REMOVAL UPDATE. + user.visible_message("\red A rib pierces the lung!") + target.rupture_lung()*/ + +/datum/surgery_step/open_encased/mend + allowed_tools = list( + /obj/item/weapon/bonegel = 100, \ + /obj/item/weapon/screwdriver = 75 + ) + + min_duration = 20 + max_duration = 40 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 2.5 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]." + var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/msg = "\blue [user] applied \the [tool] to [target]'s [affected.encased]." + var/self_msg = "\blue You applied \the [tool] to [target]'s [affected.encased]." + user.visible_message(msg, self_msg) + + affected.open = 2 \ No newline at end of file diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm index d142b8ef67c..0fa9f4863a1 100644 --- a/code/modules/surgery/eye.dm +++ b/code/modules/surgery/eye.dm @@ -12,7 +12,10 @@ var/datum/organ/external/affected = target.get_organ(target_zone) if (!affected) return 0 - return target_zone == "eyes" + + var/datum/organ/internal/eyes = target.internal_organs_by_name["eyes"] + + return target_zone == "eyes" && eyes /datum/surgery_step/eye/cut_open allowed_tools = list( diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 94c7b2b861e..a05c6f120b2 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -56,8 +56,6 @@ affected.createwound(CUT, 1) affected.clamp() spread_germs_to_organ(affected, user) - if (target_zone == "head") - target.brain_op_stage = 1 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) @@ -95,8 +93,6 @@ affected.createwound(CUT, 1) affected.clamp() affected.open = 2 - if (target_zone == "head") - target.brain_op_stage = 1 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) @@ -134,8 +130,6 @@ affected.open = 1 affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) - if (target_zone == "head") - target.brain_op_stage = 1 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) @@ -191,7 +185,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 1 && !(affected.status & ORGAN_BLEEDING) + return affected.open == 1 //&& !(affected.status & ORGAN_BLEEDING) begin_step(mob/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/implant.dm b/code/modules/surgery/implant.dm index 57df6a398c6..7e2fbc776e4 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -10,7 +10,7 @@ if(!hasorgans(target)) return 0 var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && (target_zone != "chest" || target.op_stage.ribcage == 2) + return affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) proc/get_max_wclass(datum/organ/external/affected) switch (affected.name) @@ -156,6 +156,10 @@ min_duration = 80 max_duration = 100 + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + return ..() && (!sponge || !sponge.damage) + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \ diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm new file mode 100644 index 00000000000..87675e906ef --- /dev/null +++ b/code/modules/surgery/organs_internal.dm @@ -0,0 +1,493 @@ +// Internal surgeries. +/datum/surgery_step/internal + priority = 2 + can_infect = 1 + blood_level = 1 + +/datum/surgery_step/internal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return 0 + + var/datum/organ/external/affected = target.get_organ(target_zone) + return affected.open == (affected.encased ? 3 : 2) + +////////////////////////////////////////////////////////////////// +// ALIEN EMBRYO SURGERY // +////////////////////////////////////////////////////////////////// +/datum/surgery_step/internal/remove_embryo + allowed_tools = list( + /obj/item/weapon/hemostat = 100, \ + /obj/item/weapon/wirecutters = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 20 + ) + blood_level = 2 + + min_duration = 80 + max_duration = 100 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/embryo = 0 + for(var/obj/item/alien_embryo/A in target) + embryo = 1 + break + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && embryo && affected.open == 3 && target_zone == "chest" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." + var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your chest!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\red [user] rips the larva out of [target]'s ribcage!", + "You rip the larva out of [target]'s ribcage!") + + for(var/obj/item/alien_embryo/A in target) + A.loc = A.loc.loc + + +////////////////////////////////////////////////////////////////// +// CHEST INTERNAL ORGAN SURGERY // +////////////////////////////////////////////////////////////////// +/datum/surgery_step/internal/fix_organ + allowed_tools = list( + /obj/item/stack/medical/advanced/bruise_pack= 100, \ + /obj/item/stack/medical/bruise_pack = 20, \ + /obj/item/stack/medical/bruise_pack/tajaran = 70, \ + ) + + min_duration = 70 + max_duration = 90 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/is_organ_damaged = 0 + for(var/datum/organ/internal/I in affected.internal_organs) + if(I.damage > 0) + is_organ_damaged = 1 + break + return ..() && is_organ_damaged + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/tool_name = "\the [tool]" + if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + tool_name = "regenerative membrane" + if (istype(tool, /obj/item/stack/medical/bruise_pack)) + if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) + tool_name = "the poultice" + else + tool_name = "the bandaid" + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + for(var/datum/organ/internal/I in affected.internal_organs) + if(I && I.damage > 0) + if(I.robotic < 2) + user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ + "You start treating damage to [target]'s [I.name] with [tool_name]." ) + + target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/tool_name = "\the [tool]" + if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + tool_name = "regenerative membrane" + if (istype(tool, /obj/item/stack/medical/bruise_pack)) + if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) + tool_name = "the poultice" + else + tool_name = "the bandaid" + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + for(var/datum/organ/internal/I in affected.internal_organs) + if(I && I.damage > 0) + if(I.robotic < 2) + user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ + "\blue You treat damage to [target]'s [I.name] with [tool_name]." ) + I.damage = 0 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips, getting mess and tearing the inside of [target]'s [affected.display_name] with \the [tool]!") + var/dam_amt = 2 + + if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + target.adjustToxLoss(5) + + else if (istype(tool, /obj/item/stack/medical/bruise_pack)) + if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) + target.adjustToxLoss(7) + else + dam_amt = 5 + target.adjustToxLoss(10) + affected.createwound(CUT, 5) + + for(var/datum/organ/internal/I in affected.internal_organs) + if(I && I.damage > 0) + I.take_damage(dam_amt,0) + +/datum/surgery_step/internal/fix_organ_robotic //For artificial organs + allowed_tools = list( + /obj/item/stack/nanopaste = 100, \ + /obj/item/weapon/bonegel = 30, \ + /obj/item/weapon/screwdriver = 70, \ + ) + + min_duration = 70 + max_duration = 90 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/is_organ_damaged = 0 + for(var/datum/organ/internal/I in affected.internal_organs) + if(I.damage > 0 && I.robotic >= 2) + is_organ_damaged = 1 + break + return ..() && is_organ_damaged + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + for(var/datum/organ/internal/I in affected.internal_organs) + if(I && I.damage > 0) + if(I.robotic >= 2) + user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ + "You start mending the damage to [target]'s [I.name]'s mechanisms." ) + + target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + for(var/datum/organ/internal/I in affected.internal_organs) + + if(I && I.damage > 0) + if(I.robotic >= 2) + user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \ + "\blue You repair [target]'s [I.name] with [tool]." ) + I.damage = 0 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.display_name] with \the [tool]!") + + target.adjustToxLoss(5) + affected.createwound(CUT, 5) + + for(var/datum/organ/internal/I in affected.internal_organs) + if(I) + I.take_damage(rand(3,5),0) + + +/datum/surgery_step/internal/detatch_organ + + allowed_tools = list( + /obj/item/weapon/scalpel = 100, \ + /obj/item/weapon/kitchenknife = 75, \ + /obj/item/weapon/shard = 50, \ + ) + + min_duration = 90 + max_duration = 110 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!..()) + return 0 + + target.op_stage.current_organ = null + + var/list/attached_organs = list() + for(var/organ in target.internal_organs_by_name) + var/datum/organ/internal/I = target.internal_organs_by_name[organ] + if(!I.status && I.parent_organ == target_zone) + attached_organs |= organ + + 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 + + return ..() && organ_to_remove + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/datum/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("[user] starts to separate [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You start to separate [target]'s [target.op_stage.current_organ] with \the [tool]." ) + target.custom_pain("The pain in your [affected.display_name] is living hell!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + 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/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + if(I && istype(I)) + I.status |= ORGAN_CUT_AWAY + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips, slicing an artery inside [target]'s [affected.display_name] with \the [tool]!") + affected.createwound(CUT, rand(30,50), 1) + +/datum/surgery_step/internal/remove_organ + + allowed_tools = list( + /obj/item/weapon/hemostat = 100, \ + /obj/item/weapon/wirecutters = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 20 + ) + + min_duration = 60 + max_duration = 80 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!..()) + return 0 + + target.op_stage.current_organ = null + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/datum/organ/internal/I = target.internal_organs_by_name[organ] + if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) + removable_organs |= organ + + 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 + return ..() + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] starts removing [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You start removing [target]'s [target.op_stage.current_organ] with \the [tool].") + target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "\blue You have removed [target]'s [target.op_stage.current_organ] with \the [tool].") + + // 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 = O.reagents.reagent_list["blood"] + 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) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!") + affected.createwound(BRUISE, 20) + +/datum/surgery_step/internal/replace_organ + allowed_tools = list( + /obj/item/organ = 100 + ) + + min_duration = 60 + max_duration = 80 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/obj/item/organ/O = tool + var/datum/organ/external/affected = target.get_organ(target_zone) + + var/organ_compatible + var/organ_missing + + if(!istype(O)) + return 0 + + if(target.species && target.species.has_organ[O.organ_tag]) + + if(!O.health) + user << "\red \The [O.organ_tag] is dead." + return 0 + + if(!target.internal_organs_by_name[O.organ_tag]) + organ_missing = 1 + else + user << "\red \The [target] already has a [O.organ_tag]." //TODO: grammar. + return 0 + + if(O.organ_data && affected.name == O.organ_data.parent_organ) + organ_compatible = 1 + else + user << "\red \The [O.organ_tag] doesn't normally go in \the [affected.display_name]." + return 0 + else + user << "\red \A [target.species.name] doesn't normally have a [O.organ_tag]." //TODO: grammar. + return 0 + + return ..() && organ_missing && organ_compatible + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.display_name].", \ + "You start transplanting \the [tool] into [target]'s [affected.display_name].") + target.custom_pain("Someone's rooting around in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.display_name].", \ + "\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)) + + if(!O.organ_data.transplant_data) + 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 + + 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) + + 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]!", \ + "\red Your hand slips, damaging \the [tool]!") + var/obj/item/organ/I = tool + if(istype(I)) + I.organ_data.take_damage(rand(3,5),0) + +/datum/surgery_step/internal/attach_organ + allowed_tools = list( + /obj/item/weapon/FixOVein = 100, \ + /obj/item/stack/cable_coil = 75 + ) + + min_duration = 100 + max_duration = 120 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!..()) + return 0 + + target.op_stage.current_organ = null + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/datum/organ/internal/I = target.internal_organs_by_name[organ] + if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) + removable_organs |= organ + + 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 + return ..() + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].") + target.custom_pain("Someone's digging needles into your [target.op_stage.current_organ]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + 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/datum/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] + if(I && istype(I)) + I.status &= ~ORGAN_CUT_AWAY + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips, damaging the flesh in [target]'s [affected.display_name] with \the [tool]!") + affected.createwound(BRUISE, 20) + +////////////////////////////////////////////////////////////////// +// HEART SURGERY // +////////////////////////////////////////////////////////////////// +// To be finished after some tests. +// /datum/surgery_step/ribcage/heart/cut +// allowed_tools = list( +// /obj/item/weapon/scalpel = 100, \ +// /obj/item/weapon/kitchenknife = 75, \ +// /obj/item/weapon/shard = 50, \ +// ) + +// min_duration = 30 +// max_duration = 40 + +// can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +// return ..() && target.op_stage.ribcage == 2 \ No newline at end of file diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 67f3cb82dec..ccd9d388e26 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -27,7 +27,7 @@ internal_bleeding = 1 break - return affected.open == 2 && internal_bleeding + return affected.open >= 2 && internal_bleeding begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) @@ -59,7 +59,7 @@ /obj/item/weapon/kitchenknife = 75, \ /obj/item/weapon/shard = 50, \ ) - + can_infect = 1 blood_level = 1 @@ -72,10 +72,10 @@ if (target_zone == "mouth" || target_zone == "eyes") return 0 - + var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 2 && (affected.status & ORGAN_DEAD) + return affected.open >= 2 && (affected.status & ORGAN_DEAD) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) @@ -105,7 +105,7 @@ /obj/item/weapon/reagent_containers/spray = 50, /obj/item/weapon/reagent_containers/glass/bucket = 50, ) - + can_infect = 0 blood_level = 0 @@ -115,7 +115,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!istype(tool, /obj/item/weapon/reagent_containers)) return 0 - + var/obj/item/weapon/reagent_containers/container = tool if(!container.reagents.has_reagent("peridaxon")) return 0 @@ -125,7 +125,7 @@ if (target_zone == "mouth" || target_zone == "eyes") return 0 - + var/datum/organ/external/affected = target.get_organ(target_zone) return affected.open == 3 && (affected.status & ORGAN_DEAD) @@ -138,34 +138,34 @@ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/affected = target.get_organ(target_zone) - + if (!istype(tool, /obj/item/weapon/reagent_containers)) return - + var/obj/item/weapon/reagent_containers/container = tool - + var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) if (trans > 0) container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue - + if(container.reagents.has_reagent("peridaxon")) affected.status &= ~ORGAN_DEAD - + user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.display_name]", \ "\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.display_name] with \the [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) - + if (!istype(tool, /obj/item/weapon/reagent_containers)) return - + var/obj/item/weapon/reagent_containers/container = tool - + var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue - + user.visible_message("\red [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.display_name] with the [tool]!" , \ "\red Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.display_name] with the [tool]!") - + //no damage or anything, just wastes medicine diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm deleted file mode 100644 index c14d065cd9b..00000000000 --- a/code/modules/surgery/ribcage.dm +++ /dev/null @@ -1,335 +0,0 @@ -//Procedures in this file: Generic ribcage opening steps, Removing alien embryo, Fixing internal organs. -////////////////////////////////////////////////////////////////// -// GENERIC RIBCAGE SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/ribcage - priority = 2 - can_infect = 1 - blood_level = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return target_zone == "chest" - -/datum/surgery_step/ribcage/saw_ribcage - allowed_tools = list( - /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 - ) - - min_duration = 50 - max_duration = 70 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return - var/datum/organ/external/affected = target.get_organ(target_zone) - return ..() && target.op_stage.ribcage == 0 && affected.open >= 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] begins to cut through [target]'s ribcage with \the [tool].", \ - "You begin to cut through [target]'s ribcage with \the [tool].") - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has cut [target]'s ribcage open with \the [tool].", \ - "\blue You have cut [target]'s ribcage open with \the [tool].") - target.op_stage.ribcage = 1 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, cracking [target]'s ribcage with \the [tool]!" , \ - "\red Your hand slips, cracking [target]'s ribcage with \the [tool]!" ) - var/datum/organ/external/affected = target.get_organ(target_zone) - affected.createwound(CUT, 20) - affected.fracture() - - -/datum/surgery_step/ribcage/retract_ribcage - allowed_tools = list( - /obj/item/weapon/retractor = 100, \ - /obj/item/weapon/crowbar = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - - min_duration = 30 - max_duration = 40 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.ribcage == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "[user] starts to force open the ribcage in [target]'s torso with \the [tool]." - var/self_msg = "You start to force open the ribcage in [target]'s torso with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "\blue [user] forces open [target]'s ribcage with \the [tool]." - var/self_msg = "\blue You force open [target]'s ribcage with \the [tool]." - user.visible_message(msg, self_msg) - target.op_stage.ribcage = 2 - - // Whoops! - if(prob(10)) - var/datum/organ/external/affected = target.get_organ(target_zone) - affected.fracture() - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "\red [user]'s hand slips, breaking [target]'s ribcage!" - var/self_msg = "\red Your hand slips, breaking [target]'s ribcage!" - user.visible_message(msg, self_msg) - var/datum/organ/external/affected = target.get_organ(target_zone) - affected.createwound(BRUISE, 20) - affected.fracture() - -/datum/surgery_step/ribcage/close_ribcage - allowed_tools = list( - /obj/item/weapon/retractor = 100, \ - /obj/item/weapon/crowbar = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - - - min_duration = 20 - max_duration = 40 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.ribcage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "[user] starts bending [target]'s ribcage back into place with \the [tool]." - var/self_msg = "You start bending [target]'s ribcage back into place with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "\blue [user] bends [target]'s ribcage back into place with \the [tool]." - var/self_msg = "\blue You bend [target]'s ribcage back into place with \the [tool]." - user.visible_message(msg, self_msg) - - target.op_stage.ribcage = 1 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "\red [user]'s hand slips, bending [target]'s ribs the wrong way!" - var/self_msg = "\red Your hand slips, bending [target]'s ribs the wrong way!" - user.visible_message(msg, self_msg) - var/datum/organ/external/chest/affected = target.get_organ("chest") - affected.createwound(BRUISE, 20) - affected.fracture() - if (prob(40)) - user.visible_message("\red A rib pierces the lung!") - target.rupture_lung() - -/datum/surgery_step/ribcage/mend_ribcage - allowed_tools = list( - /obj/item/weapon/bonegel = 100, \ - /obj/item/weapon/screwdriver = 75 - ) - - min_duration = 20 - max_duration = 40 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.ribcage == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "[user] starts applying \the [tool] to [target]'s ribcage." - var/self_msg = "You start applying \the [tool] to [target]'s ribcage." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "\blue [user] applied \the [tool] to [target]'s ribcage." - var/self_msg = "\blue You applied \the [tool] to [target]'s ribcage." - user.visible_message(msg, self_msg) - - target.op_stage.ribcage = 0 - -////////////////////////////////////////////////////////////////// -// ALIEN EMBRYO SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/ribcage/remove_embryo - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - blood_level = 2 - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/embryo = 0 - for(var/obj/item/alien_embryo/A in target) - embryo = 1 - break - return ..() && embryo && target.op_stage.ribcage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." - var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user] rips the larva out of [target]'s ribcage!", - "You rip the larva out of [target]'s ribcage!") - - for(var/obj/item/alien_embryo/A in target) - A.loc = A.loc.loc - - -////////////////////////////////////////////////////////////////// -// CHEST INTERNAL ORGAN SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/ribcage/fix_chest_internal - allowed_tools = list( - /obj/item/stack/medical/advanced/bruise_pack= 100, \ - /obj/item/stack/medical/bruise_pack = 20, \ - /obj/item/stack/medical/bruise_pack/tajaran = 70, \ - ) - - min_duration = 70 - max_duration = 90 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - - var/is_chest_organ_damaged = 0 - var/datum/organ/external/chest/chest = target.get_organ("chest") - for(var/datum/organ/internal/I in chest.internal_organs) - if(I.damage > 0) - is_chest_organ_damaged = 1 - break - return ..() && is_chest_organ_damaged && target.op_stage.ribcage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/tool_name = "\the [tool]" - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - tool_name = "regenerative membrane" - if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - tool_name = "the poultice" - else - tool_name = "the bandaid" - var/datum/organ/external/chest/chest = target.get_organ("chest") - for(var/datum/organ/internal/I in chest.internal_organs) - if(I && I.damage > 0) - if(I.robotic < 2) - user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ - "You start treating damage to [target]'s [I.name] with [tool_name]." ) - else - user.visible_message("[user] attempts to repair [target]'s mechanical [I.name] with [tool_name]...", \ - "\blue You attempt to repair [target]'s mechanical [I.name] with [tool_name]...") - - target.custom_pain("The pain in your chest is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/tool_name = "\the [tool]" - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - tool_name = "regenerative membrane" - if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - tool_name = "the poultice" - else - tool_name = "the bandaid" - var/datum/organ/external/chest/chest = target.get_organ("chest") - for(var/datum/organ/internal/I in chest.internal_organs) - if(I && I.damage > 0) - if(I.robotic < 2) - user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ - "\blue You treat damage to [target]'s [I.name] with [tool_name]." ) - else - user.visible_message("\blue [user] pokes [target]'s mechanical [I.name] with [tool_name]...", \ - "\blue You poke [target]'s mechanical [I.name] with [tool_name]... \red For no effect, since it's robotic.") - I.damage = 0 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ("chest") - user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s chest with \the [tool]!", \ - "\red Your hand slips, getting mess and tearing the inside of [target]'s chest with \the [tool]!") - var/dam_amt = 2 - - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - target.adjustToxLoss(5) - - else if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - target.adjustToxLoss(7) - else - dam_amt = 5 - target.adjustToxLoss(10) - affected.createwound(CUT, 5) - - for(var/datum/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0) - I.take_damage(dam_amt,0) - -/datum/surgery_step/ribcage/fix_chest_internal_robot //For artificial organs - allowed_tools = list( - /obj/item/stack/nanopaste = 100, \ - /obj/item/weapon/bonegel = 30, \ - /obj/item/weapon/screwdriver = 70, \ - ) - - min_duration = 70 - max_duration = 90 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - - var/is_chest_organ_damaged = 0 - var/datum/organ/internal/heart/heart = target.internal_organs_by_name["heart"] - var/datum/organ/external/chest/chest = target.get_organ("chest") - for(var/datum/organ/internal/I in chest.internal_organs) if(I.damage > 0) - is_chest_organ_damaged = 1 - break - return ..() && is_chest_organ_damaged && heart.robotic == 2 && target.op_stage.ribcage == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/heart/heart = target.internal_organs_by_name["heart"] - - if(heart.damage > 0) - user.visible_message("[user] starts mending the mechanisms on [target]'s heart with \the [tool].", \ - "You start mending the mechanisms on [target]'s heart with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/heart/heart = target.internal_organs_by_name["heart"] - if(heart.damage > 0) - user.visible_message("\blue [user] repairs [target]'s heart with \the [tool].", \ - "\blue You repair [target]'s heart with \the [tool]." ) - heart.damage = 0 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/internal/heart/heart = target.internal_organs_by_name["heart"] - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s heart, gumming it up!!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s heart, gumming it up!") - heart.take_damage(5, 0) - target.adjustToxLoss(5) - -////////////////////////////////////////////////////////////////// -// HEART SURGERY // -////////////////////////////////////////////////////////////////// -// To be finished after some tests. -// /datum/surgery_step/ribcage/heart/cut -// allowed_tools = list( -// /obj/item/weapon/scalpel = 100, \ -// /obj/item/weapon/kitchenknife = 75, \ -// /obj/item/weapon/shard = 50, \ -// ) - -// min_duration = 30 -// max_duration = 40 - -// can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) -// return ..() && target.op_stage.ribcage == 2 - diff --git a/code/modules/surgery/slimes.dm b/code/modules/surgery/slimes.dm new file mode 100644 index 00000000000..d962cfd3f4b --- /dev/null +++ b/code/modules/surgery/slimes.dm @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////// +// SLIME CORE EXTRACTION // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/slime + is_valid_target(mob/living/carbon/slime/target) + return istype(target, /mob/living/carbon/slime/) + + can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + return target.stat == 2 + +/datum/surgery_step/slime/cut_flesh + allowed_tools = list( + /obj/item/weapon/scalpel = 100, \ + /obj/item/weapon/kitchenknife = 75, \ + /obj/item/weapon/shard = 50, \ + ) + + min_duration = 30 + max_duration = 50 + + can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + return ..() && target.core_removal_stage == 0 + + begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \ + "You start cutting through [target]'s flesh with \the [tool].") + + end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] cuts through [target]'s flesh with \the [tool].", \ + "\blue You cut through [target]'s flesh with \the [tool], revealing its silky innards.") + target.core_removal_stage = 1 + + fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ + "\red Your hand slips, tearing [target]'s flesh with \the [tool]!") + +/datum/surgery_step/slime/cut_innards + allowed_tools = list( + /obj/item/weapon/scalpel = 100, \ + /obj/item/weapon/kitchenknife = 75, \ + /obj/item/weapon/shard = 50, \ + ) + + min_duration = 30 + max_duration = 50 + + can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + return ..() && target.core_removal_stage == 1 + + begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \ + "You start cutting [target]'s silky innards apart with \the [tool].") + + end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ + "\blue You cut [target]'s innards apart with \the [tool], exposing the cores.") + target.core_removal_stage = 2 + + fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ + "\red Your hand slips, tearing [target]'s innards with \the [tool]!") + +/datum/surgery_step/slime/saw_core + allowed_tools = list( + /obj/item/weapon/circular_saw = 100, \ + /obj/item/weapon/hatchet = 75 + ) + + min_duration = 50 + max_duration = 70 + + can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + return ..() && (istype(target) && target.core_removal_stage == 2 && target.cores > 0) //This is being passed a human as target, unsure why. + + begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \ + "You start cutting out one of [target]'s cores with \the [tool].") + + end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + target.cores-- + user.visible_message("\blue [user] cuts out one of [target]'s cores with \the [tool].",, \ + "\blue You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") + + if(target.cores >= 0) + new target.coretype(target.loc) + if(target.cores <= 0) + target.icon_state = "[target.colour] baby slime dead-nocore" + + + fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, causing \him to miss the core!", \ + "\red Your hand slips, causing you to miss the core!") \ No newline at end of file diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index b0116585ab6..9ce44d12607 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -86,12 +86,15 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool) //check if tool is right or close enough and if this step is possible if( S.tool_quality(tool) && S.can_use(user, M, user.zone_sel.selecting, tool) && S.is_valid_target(M)) S.begin_step(user, M, user.zone_sel.selecting, tool) //start on it - //We had proper tools! (or RNG smiled.) and User did not move or change hands. + //We had proper tools! (or RNG smiled.) and user did not move or change hands. if( prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration))) S.end_step(user, M, user.zone_sel.selecting, tool) //finish successfully else if (tool in user.contents && user.Adjacent(M)) //or S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~ return 1 //don't want to do weapony things after surgery + if (user.a_intent == "help") + user << "\red You can't see any useful way to use [tool] on [M]." + return 1 return 0 proc/sort_surgeries() @@ -114,5 +117,5 @@ proc/sort_surgeries() var/eyes = 0 var/face = 0 var/appendix = 0 - var/ribcage = 0 var/head_reattach = 0 + var/current_organ diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 41fda7a1505..3ebeefeba8e 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -203,7 +203,7 @@ if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob var/datum/organ/internal/brain/B = H.internal_organs_by_name["brain"] - if (B.damage < B.min_broken_damage) + if (B && B.damage < B.min_broken_damage) B.take_damage(5) else mob.setBrainLoss(50) diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index a5c7e0c7cdd..58a7aaf25c0 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm index 7707cc1a96a..561a24de2ae 100644 --- a/maps/tgstation2.dmm +++ b/maps/tgstation2.dmm @@ -2880,6 +2880,7 @@ "bdt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "bdu" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor,/area/hallway/primary/starboard) "bdv" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/turf/simulated/floor,/area/hallway/primary/starboard) +"bdw" = (/obj/machinery/optable,/obj/item/organ/brain,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "bdx" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/evahallway) "bdz" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor,/area/hallway/primary/starboard) "bdA" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/hallway/primary/starboard) @@ -8640,7 +8641,6 @@ "dkt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/aft) "dku" = (/obj/structure/table/reinforced,/obj/item/weapon/circular_saw,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dkv" = (/obj/structure/table/reinforced,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/firstaid/toxin,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"dkw" = (/obj/machinery/optable,/obj/item/brain,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dkx" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/machinery/bot/floorbot,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dky" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/item/broken_device,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dkz" = (/obj/item/weapon/organ/r_arm,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) @@ -11503,7 +11503,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUvdSrdSWdSVdStcUvdS aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUvdSrdSXcUWdStcUvdSsdSsdSsdSsdSsdSsdSYdTadSZcUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVgdOVdjWcVgdOIdjYdjSdjkdjjdjkdjjdjkdjSdjYdOIcVgdjZdkacVgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUvcUvcUvcUvcUvcUvdSsdSsdSsdSsdSsdSsdSsdSsdSscUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVgdjMcWhcVgcVgcVgcVgcVgcVgdjKcVgcVgcVgcVgcVgcVgcWjdjLcVgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscVlcVmcVmdSTcVmcVmcVmdSTcVmcVmcVmdSTcVmcVmdSUcUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadOIdjPdjOdjNdjNdjNdjNdjNdjNcVgdjNcVgdjNdjNdjNdjNdjNdjNdjOdjPdOIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUsdTbdTcdTccVzdTfdTgdThcVzdTddTddTecVzdTjdTicVycUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadOIdkqdkpdksdkrdkxdkycVgdjKcVgdjKcVgdjKcVgdkvebtdkudkwdkpdkqdOIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUsdTbdTcdTccVzdTfdTgdThcVzdTddTddTecVzdTjdTicVycUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadOIdkqdkpdksdkrdkxdkycVgdjKcVgdjKcVgdjKcVgdkvebtdkubdwdkpdkqdOIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUsdTcdTkdTbcVXdTodTndTgcVXdTmdTldTdcVXdTpcVydTqcUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadOIdjYdkpdjkdjkdjkdjkcVgdjkdjkdjkdjkdjkcVgdjkdjkdkzdjkdkpdjYdOIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVbcVgebqdkldkkdkidkjcVgdkhdjkdjkdjkdkgcVgdkfdkddkedkbebqcVgcVdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacWJcVgdkmdkmcVgcVgcVgcVgdkodjkdjkdjkdEFcVgcVgcVgcVgdkmdkmcVgcWNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa