diff --git a/baystation12.dme b/baystation12.dme index 1d8f71a79a..e6750174b3 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1650,15 +1650,14 @@ #include "code\modules\spells\targeted\projectile\projectile.dm" #include "code\modules\supermatter\supermatter.dm" #include "code\modules\surgery\bones.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\implant.dm" #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" +#include "code\modules\surgery\robotics.dm" #include "code\modules\surgery\slimes.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\tables\flipping.dm" diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 99a2dc6607..6a82c2bf5c 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -106,7 +106,7 @@ if(NOCLONE in T.mutations) return - if(T.species && T.species.flags & NO_BLOOD) + if(T.species.flags & NO_BLOOD) return // If the human is losing too much blood, beep. diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index d41ab317d9..98cc92380c 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -176,8 +176,11 @@ R.adjustBruteLoss(-1) if(wire_rate && R.getFireLoss()) R.adjustFireLoss(-1) - else - update_use_power(1) + else if(istype(occupant, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = occupant + if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450) + H.nutrition = min(H.nutrition+10, 450) + update_use_power(1) /obj/machinery/recharge_station/proc/go_out() if(!(occupant)) @@ -209,30 +212,42 @@ if(!user) return - if(!(istype(user, /mob/living/silicon/robot))) + var/can_accept_user + if(istype(user, /mob/living/silicon/robot)) + + var/mob/living/silicon/robot/R = user + + if(R.stat == 2) + //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO + return + if(occupant) + R << "The cell is already occupied!" + return + if(!R.cell) + R << "Without a powercell, you can't be recharged." + //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO + return + can_accept_user = 1 + + else if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + if(!isnull(H.internal_organs_by_name["cell"])) + can_accept_user = 1 + + if(!can_accept_user) user << "Only non-organics may enter the recharger!" return - var/mob/living/silicon/robot/R = user - if(R.stat == 2) - //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO - return - if(occupant) - R << "The cell is already occupied!" - return - if(!R.cell) - R << "Without a powercell, you can't be recharged." - //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO - return - R.stop_pulling() - if(R.client) - R.client.perspective = EYE_PERSPECTIVE - R.client.eye = src - R.loc = src - occupant = R + + user.stop_pulling() + if(user.client) + user.client.perspective = EYE_PERSPECTIVE + user.client.eye = src + user.loc = src + occupant = user /*for(var/obj/O in src) O.loc = loc*/ - add_fingerprint(R) + add_fingerprint(user) build_icon() update_use_power(1) return diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index a533b9adae..8d8076cbab 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -106,9 +106,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(location) location.hotspot_expose(700, 5) if(reagents && reagents.total_volume) // check if it has any reagents at all - if(iscarbon(loc)) - var/mob/living/carbon/C = loc - if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob + if(ishuman(loc)) + var/mob/living/carbon/human/C = loc + if (src == C.wear_mask && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.2) // Most of it is not inhaled... balance reasons. else // else just remove some of the reagents reagents.remove_any(REM) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index a8c4fbd44a..1cd40d6c89 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -81,7 +81,8 @@ return /obj/item/weapon/screwdriver/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(!istype(M)) return ..() + if(!istype(M) || user.a_intent == "help") + return ..() if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head") return ..() if((CLUMSY in user.mutations) && prob(50)) @@ -426,8 +427,11 @@ return ..() if(S.brute_dam) - S.heal_damage(15,0,0,1) - user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.name] with \the [src].") + if(S.brute_dam < ROBOLIMB_SELF_REPAIR_CAP) + S.heal_damage(15,0,0,1) + user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.name] with \the [src].") + else + user << "\red The damage is far too severe to patch over externally." return else user << "Nothing to fix!" diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 486916821b..b12fce33f8 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -92,4 +92,4 @@ desc = "A tightly furled roll of paper, covered with indecipherable runes." robotic = 2 icon = 'icons/obj/wizard.dmi' - icon_state = "scroll" \ No newline at end of file + icon_state = "scroll" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 8bc819657c..cb5b1bdf84 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1224,16 +1224,26 @@ else target_zone = user.zone_sel.selecting - switch(target_zone) - if("head") - if(head && head.flags & THICKMATERIAL) - . = 0 - else - if(wear_suit && wear_suit.flags & THICKMATERIAL) - . = 0 + var/obj/item/organ/external/affecting = get_organ(target_zone) + var/fail_msg + if(!affecting) + . = 0 + fail_msg = "They are missing that limb." + else if (affecting.status & ORGAN_ROBOT) + . = 0 + fail_msg = "That limb is robotic." + else + switch(target_zone) + if("head") + if(head && head.flags & THICKMATERIAL) + . = 0 + else + if(wear_suit && wear_suit.flags & THICKMATERIAL) + . = 0 if(!. && error_msg && user) - // Might need re-wording. - user << "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into." + if(!fail_msg) + fail_msg = "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into." + user << "[fail_msg]" /mob/living/carbon/human/print_flavor_text(var/shrink = 1) var/list/equipment = list(src.head,src.wear_mask,src.glasses,src.w_uniform,src.wear_suit,src.gloves,src.shoes) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index a198daa112..21a386b5cf 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -48,6 +48,12 @@ switch(M.a_intent) if(I_HELP) if(istype(H) && health < config.health_threshold_crit && health > config.health_threshold_dead) + if(!H.check_has_mouth()) + H << "You don't have a mouth, you cannot perform CPR!" + return + if(!check_has_mouth()) + H << "They don't have a mouth, you cannot perform CPR!" + return if((H.head && (H.head.flags & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags & MASKCOVERSMOUTH))) H << "Remove your mask!" return 0 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index ca7ed1af3d..896f57878c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -855,8 +855,6 @@ proc/handle_chemicals_in_body() - // TODO: stomach and bloodstream organ. - if(reagents) chem_effects.Cut() analgesic = 0 @@ -864,8 +862,9 @@ if(species && species.reagent_tag) alien = species.reagent_tag touching.metabolize(alien, CHEM_TOUCH) - ingested.metabolize(alien, CHEM_INGEST) - reagents.metabolize(alien, CHEM_BLOOD) + if(!(species.flags & NO_BLOOD)) + ingested.metabolize(alien, CHEM_INGEST) + reagents.metabolize(alien, CHEM_BLOOD) if(CE_PAINKILLER in chem_effects) analgesic = chem_effects[CE_PAINKILLER] @@ -1504,7 +1503,8 @@ if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) - if(species && species.flags & NO_BLOOD) return PULSE_NONE //No blood, no pulse. + if(species && species.flags & NO_BLOOD) + return PULSE_NONE //No blood, no pulse. if(stat == DEAD) return PULSE_NONE //that's it, you're dead, nothing can influence your pulse diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm index d166a65520..46a7e9f5f5 100644 --- a/code/modules/mob/living/carbon/human/species/station/slime.dm +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -8,7 +8,7 @@ language = "Sol Common" //todo? unarmed_types = list(/datum/unarmed_attack/slime_glomp) - flags = IS_RESTRICTED | NO_BLOOD | NO_SCAN | NO_SLIP | NO_BREATHE + flags = IS_RESTRICTED | NO_SCAN | NO_SLIP | NO_BREATHE siemens_coefficient = 3 darksight = 3 diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index e54447dc43..d550246d6d 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -231,7 +231,7 @@ else qdel(D) - H.visible_message("\red[H] splits apart with a wet slithering noise!") + H.visible_message("[H] splits apart with a wet slithering noise!") /datum/species/machine name = "Machine" @@ -266,7 +266,10 @@ virus_immune = 1 reagent_tag = IS_MACHINE - has_organ = list() //TODO: Positronic brain. + has_organ = list( + "brain" = /obj/item/organ/mmi_holder/posibrain, + "cell" = /obj/item/organ/cell + ) has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/ipc), diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index c7d2fee533..812a882efe 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -26,38 +26,70 @@ user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\blue Body Temperature: ???", 1) return - if(!istype(M, /mob/living/silicon/robot)) //todo add limb analysis + + var/scan_type + if(istype(M, /mob/living/silicon/robot)) + scan_type = "robot" + else if(istype(M, /mob/living/carbon/human)) + scan_type = "prosthetics" + else user << "\red You can't analyze non-robotic things!" return - user.visible_message(" [user] has analyzed [M]'s components."," You have analyzed [M]'s components.") - var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() - var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() - user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]") - user.show_message("\t Key: Electronics/Brute", 1) - user.show_message("\t Damage Specifics: [BU] - [BR]") - if(M.tod && M.stat == DEAD) - user.show_message("\blue Time of Disable: [M.tod]") + user.visible_message("\The [user] has analyzed [M]'s components.","You have analyzed [M]'s components.") + switch(scan_type) + if("robot") + var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() + var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() + user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]") + user.show_message("\t Key: Electronics/Brute", 1) + user.show_message("\t Damage Specifics: [BU] - [BR]") + if(M.tod && M.stat == DEAD) + user.show_message("\blue Time of Disable: [M.tod]") + var/mob/living/silicon/robot/H = M + var/list/damaged = H.get_damaged_components(1,1,1) + user.show_message("\blue Localized Damage:",1) + if(length(damaged)>0) + for(var/datum/robot_component/org in damaged) + user.show_message(text("\blue \t []: [][] - [] - [] - []", \ + capitalize(org.name), \ + (org.installed == -1) ? "DESTROYED " :"",\ + (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ + (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ + (org.toggled) ? "Toggled ON" : "Toggled OFF",\ + (org.powered) ? "Power ON" : "Power OFF"),1) + else + user.show_message("\blue \t Components are OK.",1) + if(H.emagged && prob(5)) + user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) + user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) - if (istype(M, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/H = M - var/list/damaged = H.get_damaged_components(1,1,1) - user.show_message("\blue Localized Damage:",1) - if(length(damaged)>0) - for(var/datum/robot_component/org in damaged) - user.show_message(text("\blue \t []: [][] - [] - [] - []", \ - capitalize(org.name), \ - (org.installed == -1) ? "DESTROYED " :"",\ - (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ - (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ - (org.toggled) ? "Toggled ON" : "Toggled OFF",\ - (org.powered) ? "Power ON" : "Power OFF"),1) - else - user.show_message("\blue \t Components are OK.",1) - if(H.emagged && prob(5)) - user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) + if("prosthetics") + var/mob/living/carbon/human/H = M + user << "Analyzing Results for \the [H]:" + user << "Key: Electronics/Brute" - user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) + user << "External prosthetics:" + var/organ_found + if(H.internal_organs.len) + for(var/obj/item/organ/external/E in H.organs) + if(!(E.status & ORGAN_ROBOT)) + continue + organ_found = 1 + user << "[E.name]: [E.brute_dam] [E.burn_dam]" + if(!organ_found) + user << "No prosthetics located." + user << "
" + user << "Internal prosthetics:" + organ_found = null + if(H.internal_organs.len) + for(var/obj/item/organ/O in H.internal_organs) + if(!(O.status & ORGAN_ROBOT)) + continue + organ_found = 1 + user << "[O.name]: [O.damage]" + if(!organ_found) + user << "No prosthetics located." src.add_fingerprint(user) return diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 272f43b790..70c2281bb3 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -214,7 +214,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Transfers blood from reagents to vessel, respecting blood types compatability. /mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount) - if(species && species.flags & NO_BLOOD) + if(species.flags & NO_BLOOD) reagents.add_reagent("blood", amount, injected.data) reagents.update_total() return diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 4b43e0edac..ecb0cb9ca2 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -349,7 +349,7 @@ This function completely restores a damaged organ to perfect condition. //Determines if we even need to process this organ. /obj/item/organ/external/proc/need_process() - if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status. + if(status & (ORGAN_CUT_AWAY|ORGAN_GAUZED|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED)) return 1 if(brute_dam || burn_dam) return 1 diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 273daa793d..28c44bc41e 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -1,6 +1,15 @@ // IPC limbs. +/obj/item/organ/external/head/ipc + dislocated = -1 + can_intake_reagents = 0 + encased = null +/obj/item/organ/external/head/ipc/New() + robotize("Morpheus Cyberkinetics") + ..() + /obj/item/organ/external/chest/ipc dislocated = -1 + encased = null /obj/item/organ/external/chest/ipc/New() robotize("Morpheus Cyberkinetics") ..() @@ -59,9 +68,74 @@ robotize("Morpheus Cyberkinetics") ..() -/obj/item/organ/external/head/ipc - dislocated = -1 - can_intake_reagents = 0 -/obj/item/organ/external/head/ipc/New() - robotize("Morpheus Cyberkinetics") +/obj/item/organ/cell + name = "microbattery" + desc = "A small, powerful cell for use in fully prosthetic bodies." + icon = 'icons/obj/power.dmi' + icon_state = "scell" + organ_tag = "cell" + parent_organ = "chest" + vital = 1 + +/obj/item/organ/cell/New() + robotize() ..() + +/obj/item/organ/cell/replaced() + ..() + // This is very ghetto way of rebooting an IPC. TODO better way. + if(owner && owner.stat == DEAD) + owner.stat = 0 + owner.visible_message("\The [owner] twitches visibly!") + +// Used for an MMI or posibrain being installed into a human. +/obj/item/organ/mmi_holder + name = "brain" + organ_tag = "brain" + parent_organ = "head" + vital = 1 + var/obj/item/device/mmi/stored_mmi + +/obj/item/organ/mmi_holder/proc/update_from_mmi() + if(!stored_mmi) + return + name = stored_mmi.name + desc = stored_mmi.desc + icon = stored_mmi.icon + icon_state = stored_mmi.icon_state + +/obj/item/organ/mmi_holder/removed(var/mob/living/user) + + if(stored_mmi) + stored_mmi.loc = get_turf(src) + if(owner.mind) + owner.mind.transfer_to(stored_mmi.brainmob) + ..() + + var/mob/living/holder_mob = loc + if(istype(holder_mob)) + holder_mob.drop_from_inventory(src) + qdel(src) + +/obj/item/organ/mmi_holder/New() + ..() + // This is very ghetto way of rebooting an IPC. TODO better way. + spawn(1) + if(owner && owner.stat == DEAD) + owner.stat = 0 + owner.visible_message("\The [owner] twitches visibly!") + +/obj/item/organ/mmi_holder/posibrain/New() + robotize() + stored_mmi = new /obj/item/device/mmi/digital/posibrain(src) + ..() + spawn(1) + if(owner) + stored_mmi.name = "positronic brain ([owner.name])" + stored_mmi.brainmob.real_name = owner.name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.icon_state = "posibrain-occupied" + update_from_mmi() + else + stored_mmi.loc = get_turf(src) + qdel(src) \ No newline at end of file diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 6f9176640e..d883054b1b 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -520,8 +520,11 @@ obj/structure/cable/proc/cableColor(var/colorC) return ..() if(S.burn_dam > 0 && use(1)) - S.heal_damage(0,15,0,1) - user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].") + if(S.burn_dam < ROBOLIMB_SELF_REPAIR_CAP) + S.heal_damage(0,15,0,1) + user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].") + else + user << "\red The damage is far too severe to patch over externally." return else user << "Nothing to fix!" diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 0e0da75e2a..2d8ece18c1 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -1,11 +1,11 @@ /datum/reagent var/name = "Reagent" var/id = "reagent" - var/description = "A non-descript chemical." + var/description = "A non-descript chemical." var/datum/reagents/holder = null var/reagent_state = SOLID var/list/data = null - var/volume = 0 + var/volume = 0 var/metabolism = REM // This would be 0.2 normally var/ingest_met = 0 var/touch_met = 0 @@ -13,11 +13,11 @@ var/max_dose = 0 var/overdose = 0 var/scannable = 0 // Shows up on health analyzers. - var/affects_dead = 0 + var/affects_dead = 0 var/glass_icon_state = null var/glass_name = null var/glass_desc = null - var/glass_center_of_mass = null + var/glass_center_of_mass = null var/color = "#000000" var/color_weight = 1 @@ -86,11 +86,11 @@ return data.Copy() else if(data) return data - return null + return null /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references ..() - holder = null + holder = null /* DEPRECATED - TODO: REMOVE EVERYWHERE */ @@ -108,4 +108,4 @@ id = "woodpulp" description = "A mass of wood fibers." reagent_state = LIQUID - color = "#B97A57" + color = "#B97A57" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index cafd3aed25..c7afddee39 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -57,6 +57,8 @@ M.adjustToxLoss(removed) /datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_MACHINE) + return if(data && data["viruses"]) for(var/datum/disease/D in data["viruses"]) if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index ba2ff23ac7..2f9cc0f548 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -305,8 +305,6 @@ return /datum/reagent/condensedcapsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - if(alien == IS_DIONA || alien == IS_MACHINE) - return if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.species && (H.species.flags & (NO_PAIN))) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index b739671312..9f8e05a20b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -229,6 +229,9 @@ affect_blood(M, alien, removed) /datum/reagent/mutagen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/mob/living/carbon/human/H = M + if(istype(H) && (H.species.flags & NO_SCAN)) + return if(M.dna) if(prob(removed * 0.1)) // Approx. one mutation per 10 injected/20 ingested/30 touching units randmuti(M) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 985ed3d9d2..b57830e1d6 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -65,6 +65,16 @@ if (!istype(M)) return + var/mob/living/carbon/human/H = M + if(istype(H)) + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + user << "\The [H] is missing that limb!" + return + else if(affected.status & ORGAN_ROBOT) + user << "You cannot inject a robotic limb." + return + if (R.total_volume && M.can_inject(user, 1)) user << "You inject [M] with the injector." M << "You feel a tiny prick!" diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index c5153510d7..f39d7167fa 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -25,6 +25,17 @@ return if (!istype(M)) return + + var/mob/living/carbon/human/H = M + if(istype(H)) + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + user << "\The [H] is missing that limb!" + return + else if(affected.status & ORGAN_ROBOT) + user << "You cannot inject a robotic limb." + return + user << "You inject [M] with [src]." M << "You feel a tiny prick!" diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index c7f869802b..bdc17b298c 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -142,13 +142,21 @@ user << "[target] is full." return + var/mob/living/carbon/human/H = target + if(istype(H)) + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + user << "\The [H] is missing that limb!" + return + else if(affected.status & ORGAN_ROBOT) + user << "You cannot inject a robotic limb." + return + if(ismob(target) && target != user) var/injtime = time //Injecting through a hardsuit takes longer due to needing to find a port. - if(istype(target, /mob/living/carbon/human)) - - var/mob/living/carbon/human/H = target + if(istype(H)) if(H.wear_suit) if(istype(H.wear_suit, /obj/item/clothing/suit/space)) injtime = injtime * 2 diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index bbeb1603b7..3368c8344d 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -130,7 +130,7 @@ /obj/machinery/power/supermatter/proc/announce_warning() var/integrity = get_integrity() var/alert_msg = " Integrity at [integrity]%" - + if(damage > emergency_point) alert_msg = emergency_alert + alert_msg lastwarning = world.timeofday - WARNING_DELAY * 4 @@ -153,7 +153,7 @@ else if(safe_warned && public_alert) radio.autosay(alert_msg, "Supermatter Monitor") public_alert = 0 - + /obj/machinery/power/supermatter/process() diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index b2ccbb1003..25addbd40a 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -18,7 +18,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open >= 2 && affected.stage == 0 + return affected && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 0 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -52,7 +52,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.name != "head" && affected.open >= 2 && affected.stage == 1 + return affected && affected.name != "head" && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -91,7 +91,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.name == "head" && affected.open >= 2 && affected.stage == 1 + return affected && affected.name == "head" && !(affected.status & ORGAN_ROBOT) && 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/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open >= 2 && affected.stage == 2 + return affected && affected.open >= 2 && !(affected.status & ORGAN_ROBOT) && affected.stage == 2 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm deleted file mode 100644 index 6935b09d24..0000000000 --- a/code/modules/surgery/brainrepair.dm +++ /dev/null @@ -1,70 +0,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/material/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/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return - var/obj/item/organ/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/obj/item/organ/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/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return - var/obj/item/organ/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/obj/item/organ/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 index 8e1a516384..1744cec3d7 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -12,7 +12,7 @@ return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.encased && affected.open >= 2 + return affected && !(affected.status & ORGAN_ROBOT) && affected.encased && affected.open >= 2 /datum/surgery_step/open_encased/saw diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm deleted file mode 100644 index 7b69fea7ff..0000000000 --- a/code/modules/surgery/eye.dm +++ /dev/null @@ -1,147 +0,0 @@ -//Procedures in this file: Eye mending surgery -////////////////////////////////////////////////////////////////// -// EYE SURGERY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/eye - priority = 2 - can_infect = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (!affected) - return 0 - - var/obj/item/organ/eyes = target.internal_organs_by_name["eyes"] - - return target_zone == "eyes" && eyes - -/datum/surgery_step/eye/cut_open - allowed_tools = list( - /obj/item/weapon/scalpel = 100, \ - /obj/item/weapon/material/knife = 75, \ - /obj/item/weapon/material/shard = 50, \ - ) - - min_duration = 90 - max_duration = 110 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts to separate the corneas on [target]'s eyes with \the [tool].", \ - "You start to separate the corneas on [target]'s eyes with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has separated the corneas on [target]'s eyes with \the [tool]." , \ - "\blue You have separated the corneas on [target]'s eyes with \the [tool].",) - target.op_stage.eyes = 1 - target.blinded += 1.5 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing [target]'s eyes wth \the [tool]!" , \ - "\red Your hand slips, slicing [target]'s eyes wth \the [tool]!" ) - affected.createwound(CUT, 10) - eyes.take_damage(5, 0) - -/datum/surgery_step/eye/lift_eyes - allowed_tools = list( - /obj/item/weapon/retractor = 100, \ - /obj/item/weapon/material/kitchen/utensil/fork = 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.eyes == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts lifting corneas from [target]'s eyes with \the [tool].", \ - "You start lifting corneas from [target]'s eyes with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has lifted the corneas from [target]'s eyes from with \the [tool]." , \ - "\blue You has lifted the corneas from [target]'s eyes from with \the [tool]." ) - target.op_stage.eyes = 2 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging [target]'s eyes with \the [tool]!", \ - "\red Your hand slips, damaging [target]'s eyes with \the [tool]!") - target.apply_damage(10, BRUTE, affected) - eyes.take_damage(5, 0) - -/datum/surgery_step/eye/mend_eyes - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity. - ) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.eyes == 2 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts mending the nerves and lenses in [target]'s eyes with \the [tool].", \ - "You start mending the nerves and lenses in [target]'s eyes with the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] mends the nerves and lenses in [target]'s with \the [tool]." , \ - "\blue You mend the nerves and lenses in [target]'s with \the [tool].") - target.op_stage.eyes = 3 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, stabbing \the [tool] into [target]'s eye!", \ - "\red Your hand slips, stabbing \the [tool] into [target]'s eye!") - target.apply_damage(10, BRUTE, affected, sharp=1) - eyes.take_damage(5, 0) - -/datum/surgery_step/eye/cauterize - allowed_tools = list( - /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/weapon/flame/lighter = 50, \ - /obj/item/weapon/weldingtool = 25 - ) - - min_duration = 70 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] is beginning to cauterize the incision around [target]'s eyes with \the [tool]." , \ - "You are beginning to cauterize the incision around [target]'s eyes with \the [tool].") - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - user.visible_message("\blue [user] cauterizes the incision around [target]'s eyes with \the [tool].", \ - "\blue You cauterize the incision around [target]'s eyes with \the [tool].") - if (target.op_stage.eyes == 3) - target.disabilities &= ~NEARSIGHTED - target.sdisabilities &= ~BLIND - eyes.damage = 0 - target.op_stage.eyes = 0 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, searing [target]'s eyes with \the [tool]!", \ - "\red Your hand slips, searing [target]'s eyes with \the [tool]!") - target.apply_damage(5, BURN, affected) - eyes.take_damage(5, 0) \ No newline at end of file diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 0a42f7c137..7272ecf49e 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -10,7 +10,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (!affected) + if (!affected || (affected.status & ORGAN_ROBOT)) return 0 return target_zone == "mouth" diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 95980d5252..62cf65b2ce 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -32,6 +32,12 @@ return "abdominal" return "" + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!") + affected.createwound(CUT, 20) + /datum/surgery_step/cavity/make_space allowed_tools = list( /obj/item/weapon/surgicaldrill = 100, \ @@ -60,12 +66,6 @@ user.visible_message("\blue [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ "\blue You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) - /datum/surgery_step/cavity/close_space priority = 2 allowed_tools = list( @@ -96,12 +96,6 @@ user.visible_message("\blue [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \ "\blue You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." ) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) - /datum/surgery_step/cavity/place_item priority = 0 allowed_tools = list(/obj/item = 100) @@ -126,7 +120,7 @@ user.visible_message("\blue [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ "\blue You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) - if (tool.w_class > get_max_wclass(affected)/2 && prob(50)) + if (tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT)) user << "\red You tear some blood vessels trying to fit such a big object in this cavity." var/datum/wound/internal_bleeding/I = new (10) affected.wounds += I @@ -136,12 +130,6 @@ tool.loc = target affected.cavity = 0 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) - ////////////////////////////////////////////////////////////////// // IMPLANT/ITEM REMOVAL SURGERY // ////////////////////////////////////////////////////////////////// @@ -162,9 +150,9 @@ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.name] with \the [tool].", \ - "You start poking around inside the incision on [target]'s [affected.name] with \the [tool]" ) - target.custom_pain("The pain in your chest is living hell!",1) + user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ + "You start poking around inside [target]'s [affected.name] with \the [tool]" ) + target.custom_pain("The pain in your [affected.name] is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -209,8 +197,8 @@ user.visible_message("\blue [user] removes \the [tool] from [target]'s [affected.name].", \ "\blue There's something inside [target]'s [affected.name], but you just missed it this time." ) else if (affected.hidden) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \ - "\blue You take something out of incision on [target]'s [affected.name]s with \the [tool]." ) + user.visible_message("\blue [user] takes something out of [target]'s [affected.name] with \the [tool].", \ + "\blue You take something out of [target]'s [affected.name]s with \the [tool]." ) affected.hidden.loc = get_turf(target) if(!affected.hidden.blood_DNA) affected.hidden.blood_DNA = list() @@ -223,10 +211,8 @@ "\blue You could not find anything inside [target]'s [affected.name]." ) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + ..() var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) if (affected.implants.len) var/fail_prob = 10 fail_prob += 100 - tool_quality(tool) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index a97184f35c..d352c4aed4 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -138,75 +138,6 @@ 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/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return - var/is_organ_damaged = 0 - for(var/obj/item/organ/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/obj/item/organ/external/affected = target.get_organ(target_zone) - - for(var/obj/item/organ/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.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/obj/item/organ/external/affected = target.get_organ(target_zone) - - for(var/obj/item/organ/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/obj/item/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.name] with \the [tool]!", \ - "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") - - target.adjustToxLoss(5) - affected.createwound(CUT, 5) - - for(var/obj/item/organ/I in affected.internal_organs) - if(I) - I.take_damage(rand(3,5),0) - - /datum/surgery_step/internal/detatch_organ allowed_tools = list( @@ -223,12 +154,17 @@ if (!..()) return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + if(!(affected && !(affected.status & ORGAN_ROBOT))) + return 0 + target.op_stage.current_organ = null var/list/attached_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && !I.status && I.parent_organ == target_zone) + if(I && !(I.status & ORGAN_CUT_AWAY) && 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 @@ -283,7 +219,7 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) + 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 @@ -312,8 +248,8 @@ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!") + user.visible_message("\red [user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + "\red Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") affected.createwound(BRUISE, 20) /datum/surgery_step/internal/replace_organ @@ -335,6 +271,10 @@ if(!istype(O)) return 0 + if((affected.status & ORGAN_ROBOT) && !(O.status & ORGAN_ROBOT)) + user << "You cannot install a naked organ into a robotic body." + return 2 + if(!target.species) user << "\red You have no idea what species this person is. Report this on the bug tracker." return 2 @@ -410,7 +350,7 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone) + if(I && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && 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 diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm new file mode 100644 index 0000000000..074ccda0c6 --- /dev/null +++ b/code/modules/surgery/robotics.dm @@ -0,0 +1,417 @@ +//Procedures in this file: Gneric surgery steps +////////////////////////////////////////////////////////////////// +// COMMON STEPS // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/robotics/ + can_infect = 0 + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (isslime(target)) + return 0 + if (target_zone == "eyes") //there are specific steps for eye surgery + return 0 + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected == null) + return 0 + if (affected.status & ORGAN_DESTROYED) + return 0 + if (!(affected.status & ORGAN_ROBOT)) + return 0 + return 1 + +/datum/surgery_step/robotics/unscrew_hatch + allowed_tools = list( + /obj/item/weapon/screwdriver = 100, + /obj/item/weapon/coin = 50, + /obj/item/weapon/material/kitchen/utensil/knife = 50 + ) + + min_duration = 90 + max_duration = 110 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 0 && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + "You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + "\blue You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",) + affected.open = 1 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \ + "\red Your [tool] slips, failing to unscrew [target]'s [affected.name].") + +/datum/surgery_step/robotics/open_hatch + allowed_tools = list( + /obj/item/weapon/retractor = 100, + /obj/item/weapon/crowbar = 100, + /obj/item/weapon/material/kitchen/utensil = 50 + ) + + min_duration = 30 + max_duration = 40 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == 1 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].", + "You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] open the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + "\blue You open the maintenance hatch on [target]'s [affected.name] with \the [tool]." ) + affected.open = 2 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].", + "\red Your [tool] slips, failing to open the hatch on [target]'s [affected.name].") + +/datum/surgery_step/robotics/close_hatch + allowed_tools = list( + /obj/item/weapon/retractor = 100, + /obj/item/weapon/crowbar = 100, + /obj/item/weapon/material/kitchen/utensil = 50 + ) + + min_duration = 70 + max_duration = 100 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \ + "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ + "\blue You close and secure the hatch on [target]'s [affected.name] with \the [tool].") + affected.open = 0 + affected.germ_level = 0 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", + "\red Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") + +/datum/surgery_step/robotics/repair_brute + allowed_tools = list( + /obj/item/weapon/weldingtool = 100, + /obj/item/weapon/pickaxe/plasmacutter = 50 + ) + + min_duration = 50 + max_duration = 60 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && affected.brute_dam > 0 && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ + "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ + "\blue You finish patching damage to [target]'s [affected.name] with \the [tool].") + affected.heal_damage(rand(30,50),0) + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", + "\red Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") + target.apply_damage(rand(5,10), BURN, affected) + +/datum/surgery_step/robotics/repair_burn + allowed_tools = list( + /obj/item/stack/cable_coil = 100 + ) + + min_duration = 50 + max_duration = 60 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open && affected.burn_dam > 0 && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \ + "You begin to splice new cabling into [target]'s [affected.name].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] finishes splicing cable into [target]'s [affected.name].", \ + "\blue You finishes splicing new cable into [target]'s [affected.name].") + affected.heal_damage(0,rand(30,50)) + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user] causes a short circuit in [target]'s [affected.name]!", + "\red You cause a short circuit in [target]'s [affected.name]!") + target.apply_damage(rand(5,10), BURN, affected) + +/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs + allowed_tools = list( + /obj/item/stack/nanopaste = 100, \ + /obj/item/weapon/bonegel = 30, \ + /obj/item/weapon/screwdriver = 70, \ + ) + + 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/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return + var/is_organ_damaged = 0 + for(var/obj/item/organ/I in affected.internal_organs) + if(I.damage > 0 && I.robotic >= 2) + is_organ_damaged = 1 + break + return affected.open == 2 && is_organ_damaged + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + for(var/obj/item/organ/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.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/obj/item/organ/external/affected = target.get_organ(target_zone) + + for(var/obj/item/organ/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/obj/item/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.name] with \the [tool]!", \ + "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") + + target.adjustToxLoss(5) + affected.createwound(CUT, 5) + + for(var/obj/item/organ/I in affected.internal_organs) + if(I) + I.take_damage(rand(3,5),0) + +/datum/surgery_step/robotics/detatch_organ_robotic + + allowed_tools = list( + /obj/item/device/multitool = 100 + ) + + min_duration = 90 + max_duration = 110 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!(affected && (affected.status & ORGAN_ROBOT))) + return 0 + if(affected.open != 2) + return 0 + + target.op_stage.current_organ = null + + var/list/attached_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/I = target.internal_organs_by_name[organ] + if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + attached_organs |= organ + + 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) + user.visible_message("[user] starts to decouple [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You start to decouple [target]'s [target.op_stage.current_organ] with \the [tool]." ) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\blue [user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \ + "\blue You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].") + + var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] + if(I && istype(I)) + I.status |= ORGAN_CUT_AWAY + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ + "\red Your hand slips, disconnecting \the [tool].") + +/datum/surgery_step/robotics/attach_organ_robotic + allowed_tools = list( + /obj/item/weapon/screwdriver = 100, + ) + + min_duration = 100 + max_duration = 120 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!(affected && (affected.status & ORGAN_ROBOT))) + return 0 + if(affected.open != 2) + return 0 + + target.op_stage.current_organ = null + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/I = target.internal_organs_by_name[organ] + if(I && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) + removable_organs |= organ + + 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].") + ..() + + 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/obj/item/organ/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) + user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ + "\red Your hand slips, disconnecting \the [tool].") + +/datum/surgery_step/robotics/install_mmi + allowed_tools = list( + /obj/item/device/mmi = 100 + ) + + min_duration = 60 + max_duration = 80 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + if(target_zone != "head") + return + + var/obj/item/device/mmi/M = tool + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!(affected && affected.open == 2)) + return 0 + + if(!istype(M)) + return 0 + + if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) + user << "That brain is not usable." + return 2 + + if(!(affected.status & ORGAN_ROBOT)) + user << "You cannot install a computer brain into a meat skull." + return 2 + + if(!target.species) + user << "You have no idea what species this person is. Report this on the bug tracker." + return 2 + + if(!target.species.has_organ["brain"]) + user << "You're pretty sure [target.species.name_plural] don't normally have a brain." + return 2 + + if(!isnull(target.internal_organs["brain"])) + user << "Your subject already has a brain." + return 2 + + return 1 + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ + "You start installing \the [tool] into [target]'s [affected.name].") + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has installed \the [tool] into [target]'s [affected.name].", \ + "\blue You have installed \the [tool] into [target]'s [affected.name].") + + var/obj/item/device/mmi/M = tool + var/obj/item/organ/mmi_holder/holder = new(target, 1) + target.internal_organs_by_name["brain"] = holder + user.drop_from_inventory(tool) + tool.loc = holder + holder.stored_mmi = tool + holder.update_from_mmi() + + if(M.brainmob && M.brainmob.mind) + M.brainmob.mind.transfer_to(target) + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("\red [user]'s hand slips.", \ + "\red Your hand slips.") \ No newline at end of file diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm index 7508818a6d..d318ca9f8a 100644 --- a/code/modules/virus2/items_devices.dm +++ b/code/modules/virus2/items_devices.dm @@ -16,7 +16,7 @@ var/mob/living/carbon/C = M if (istype(C,/mob/living/carbon/human/)) var/mob/living/carbon/human/H = C - if(H.species && H.species.flags & NO_BLOOD) + if(H.species.flags & NO_BLOOD) report("Scan aborted: The target does not have blood.", user) return diff --git a/code/setup.dm b/code/setup.dm index 865a6e0a43..80074d2afc 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -984,3 +984,5 @@ var/list/be_special_flags = list( #define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass) +// Damage above this value must be repaired with surgery. +#define ROBOLIMB_SELF_REPAIR_CAP 30 \ No newline at end of file