diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index e2db0360125..ca7ccf94c1a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -115,6 +115,7 @@ new /obj/item/weapon/storage/belt/medical(src) new /obj/item/device/flash/handheld(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) + new /obj/item/cybernetic_implant/eyes/hud/medical(src) return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index f20afceaaa3..b51e729b8d0 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -266,7 +266,7 @@ if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/obj/item/cybernetic_implant/eyes/hud/CIH = locate(/obj/item/cybernetic_implant/eyes/hud) in internal_organs + var/obj/item/cybernetic_implant/eyes/hud/CIH = locate(/obj/item/cybernetic_implant/eyes/hud) in H.internal_organs if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH) var/perpname = get_face_name(get_id_name("")) if(perpname) @@ -276,6 +276,12 @@ msg += "\[Front photo\] " msg += "\[Side photo\]
" if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/cybernetic_implant/eyes/hud/medical)) + var/implant_detect + for(var/obj/item/cybernetic_implant/CI in internal_organs) + implant_detect += "[name] is modified with a [CI.name].
" + if(implant_detect) + msg += "Detected cybernetic modifications:
" + msg += implant_detect if(R) var/health = R.fields["p_stat"] msg += "\[[health]\]" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 2c7ae702d64..ff9be3891c2 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -102,7 +102,7 @@ datum/design/bluespacebodybag name = "Medical HUD implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." id = "ci-medhud" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4) + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 100) build_path = /obj/item/cybernetic_implant/eyes/hud/medical @@ -112,7 +112,7 @@ datum/design/bluespacebodybag name = "Security HUD implant" desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." id = "ci-sechud" - req_tech = list("materials" = 5, "programming" = 5, "biotech" = 5, "combat" = 2) + req_tech = list("materials" = 6, "programming" = 5, "biotech" = 4, "combat" = 2) build_type = PROTOLATHE | MECHFAB materials = list("$metal" = 200, "$glass" = 200, "$silver" = 300, "$gold" = 300) build_path = /obj/item/cybernetic_implant/eyes/hud/security @@ -122,38 +122,65 @@ datum/design/bluespacebodybag name = "X-Ray implant" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." id = "ci-xray" - req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "plasmatech" = 3) + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5, "plasmatech" = 3) build_type = PROTOLATHE | MECHFAB - materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 500) + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$uranium" = 500, "$diamond" = 1000) build_path = /obj/item/cybernetic_implant/eyes/xray category = list("Medical Designs") -/datum/design/cyberimb_thermals +/datum/design/cyberimp_thermals name = "Thermals implant" desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." id = "ci-thermals" - req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "plasmatech" = 3) + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "plasmatech" = 3, "syndicate" = 4) build_type = PROTOLATHE | MECHFAB - materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 500) + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 1000) build_path = /obj/item/cybernetic_implant/eyes/thermals category = list("Medical Designs") -/datum/design/cyberimb_antidrop +/datum/design/cyberimp_antidrop name = "Anti-Drop implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." id = "ci-antidrop" - req_tech = list("materials" = 6, "programming" = 5, "biotech" = 5) + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5) build_type = PROTOLATHE | MECHFAB materials = list("$metal" = 200, "$glass" = 200, "$silver" = 400, "$gold" = 400) build_path = /obj/item/cybernetic_implant/brain/anti_drop category = list("Medical Designs") -/datum/design/cyberimb_antistun +/datum/design/cyberimp_antistun name = "CNS Rebooter implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." id = "ci-antistun" - req_tech = list("materials" = 6, "programming" = 5, "biotech" = 5) + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6) build_type = PROTOLATHE | MECHFAB - materials = list("$metal" = 200, "$glass" = 200, "$silver" = 400, "$gold" = 600) + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 500, "$gold" = 1000) build_path = /obj/item/cybernetic_implant/brain/anti_stun + category = list("Medical Designs") + +/datum/design/cyberimp_nutriment + name = "Nutriment pump implant" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." + id = "ci-nutriment" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$gold" = 500, "$uranium" = 500) + category = list("Medical Designs") + +/datum/design/cyberimp_nutriment_plus + name = "Nutriment pump implant PLUS" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." + id = "ci-nutrimentplus" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$gold" = 500, "$uranium" = 750) + category = list("Medical Designs") + +/datum/design/cyberimp_reviver + name = "Reviver implant" + desc = "This implant will automatically deliver a therapeutic dose of electrical energy to your heart if it ever stops beating, and inject you with nanites. A second chance!" + id = "ci-reviver" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 500, "$gold" = 1000, "$uranium" = 1000, "$diamond" = 2000) category = list("Medical Designs") \ No newline at end of file diff --git a/code/modules/surgery/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm index 6d289144127..66792e9c61b 100644 --- a/code/modules/surgery/cybernetic_implants.dm +++ b/code/modules/surgery/cybernetic_implants.dm @@ -1,48 +1,74 @@ #define MAX_BRAIN_IMPLANT 2 +#define MAX_CHEST_IMPLANT 3 +/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/implant, datum/surgery/surgery) + user.visible_message("[user] begins to implant [target] with [implant].") + +//[[[[EYES]]]] /datum/surgery/eye_cybernetic_implant/eyes name = "eye cybernetic implant" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/cybernetic_implant/eyes, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) location = "eyes" -/datum/surgery/eye_cybernetic_implant/brain - name = "brain cybernetic implant" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/brain, /datum/surgery_step/close) - location = "head" - /datum/surgery_step/cybernetic_implant/eyes implements = list(/obj/item/cybernetic_implant/eyes = 100) time = 32 -/datum/surgery_step/cybernetic_implant/brain - implements = list(/obj/item/cybernetic_implant/brain = 100) - time = 32 - -/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/implant, datum/surgery/surgery) - user.visible_message("[user] begins to implant [target] with [implant].") - /datum/surgery_step/cybernetic_implant/eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/eyes/implant, datum/surgery/surgery) if(implant) var/full = 0 if(locate(/obj/item/cybernetic_implant/eyes,target.internal_organs)) full = 1 - insert(user,target,implant,target_zone,full) return 1 +//[[[[BRAIN]]]] +/datum/surgery/eye_cybernetic_implant/brain + name = "brain cybernetic implant" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/brain, /datum/surgery_step/close) + location = "head" + +/datum/surgery_step/cybernetic_implant/brain + implements = list(/obj/item/cybernetic_implant/brain = 100) + time = 32 + /datum/surgery_step/cybernetic_implant/brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/brain/implant, datum/surgery/surgery) if(implant) var/full = 0 - for(var/obj/item/I in target.contents) + for(var/obj/item/I in target.internal_organs) if(istype(I,/obj/item/cybernetic_implant/brain)) full++ if(full < MAX_BRAIN_IMPLANT) full = 0 - insert(user,target,implant,target_zone,full) return 1 +//[[[[CHEST]]]] +/datum/surgery/eye_cybernetic_implant/chest + name = "torso cybernetic implant" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/chest, /datum/surgery_step/close) + location = "chest" + +/datum/surgery_step/cybernetic_implant/chest + implements = list(/obj/item/cybernetic_implant/chest = 100) + time = 32 + +/datum/surgery_step/cybernetic_implant/chest/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/chest/implant, datum/surgery/surgery) + if(implant) + var/full = 0 + for(var/obj/item/I in target.internal_organs) + if(istype(I,/obj/item/cybernetic_implant/chest)) + full++ + if(full < MAX_CHEST_IMPLANT) + full = 0 + + if(istype(implant,/obj/item/cybernetic_implant/chest/heart)) + if(locate(/obj/item/cybernetic_implant/chest/heart) in target.internal_organs) + full = 1 + + insert(user,target,implant,target_zone,full) + return 1 /datum/surgery_step/cybernetic_implant/proc/insert(mob/user, mob/living/carbon/target, obj/item/cybernetic_implant/implant,target_zone,full) if(full) @@ -52,5 +78,5 @@ implant.owner = target implant.function() user.drop_item() - implant.loc = target - target.internal_organs |= implant \ No newline at end of file + target.internal_organs |= implant + implant.loc = target \ No newline at end of file diff --git a/code/modules/surgery/organs/cybernetic_implants.dm b/code/modules/surgery/organs/cybernetic_implants.dm index 5b5a928148b..acc621aa7a7 100644 --- a/code/modules/surgery/organs/cybernetic_implants.dm +++ b/code/modules/surgery/organs/cybernetic_implants.dm @@ -8,8 +8,7 @@ var/implant_color = "#FFFFFF" /obj/item/cybernetic_implant/New(var/mob/M = null) - if(M) - owner = M + owner = M return ..() /obj/item/cybernetic_implant/proc/function() @@ -40,10 +39,11 @@ owner << "[fluff_message]" /obj/item/cybernetic_implant/eyes/hud/medical - name = "medical hud implant" + name = "Medical HUD implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." eye_color = "0ff" implant_color = "#00FFFF" + origin_tech = "materials=4;programming=3;biotech=4" /obj/item/cybernetic_implant/eyes/hud/medical/function() if(!owner) @@ -55,10 +55,11 @@ update_eye_color("You suddenly see health bars floating above people's heads...") /obj/item/cybernetic_implant/eyes/hud/security - name = "security hud implant" + name = "Security HUD implant" desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." eye_color = "d00" implant_color = "#CC0000" + origin_tech = "materials=4;programming=4;biotech=3;combat=1" /obj/item/cybernetic_implant/eyes/hud/security/function() if(!owner) @@ -70,10 +71,11 @@ update_eye_color("Job indicator icons pop up in your vision. That is not a certified surgeon...") /obj/item/cybernetic_implant/eyes/xray - name = "xray implant" + name = "X-ray implant" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." eye_color = "000" implant_color = "#000000" + origin_tech = "materials=6;programming=4;biotech=5;magnets=5;plasmatech=2" /obj/item/cybernetic_implant/eyes/xray/function() if(!owner) @@ -88,11 +90,12 @@ update_eye_color("Your vision is augmented!") /obj/item/cybernetic_implant/eyes/thermals - name = "thermals implant" + name = "Thermals implant" desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." eye_color = "FC0" implant_color = "#FFCC00" flash_protect = -1 + origin_tech = "materials=6;programming=4;biotech=5;magnets=5;plasmatech=2;syndicate=4" /obj/item/cybernetic_implant/eyes/thermals/function() if(!owner) @@ -103,6 +106,8 @@ update_eye_color("You see prey everywhere you look...") /obj/item/cybernetic_implant/eyes/emp_act(severity) + if(!owner) + return if(severity > 1) if(prob(5)) return @@ -129,13 +134,15 @@ ..() /obj/item/cybernetic_implant/brain/emp_act(severity) + if(!owner) + return var/stun_amount = 5 + (severity-1 ? 0 : 5) owner.Stun(stun_amount) owner << "Your body seizes up!" return stun_amount /obj/item/cybernetic_implant/brain/anti_drop - name = "anti-drop implant" + name = "Anti-drop implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." var/active = 0 var/l_hand_ignore = 0 @@ -143,6 +150,7 @@ var/obj/item/l_hand_obj = null var/obj/item/r_hand_obj = null implant_color = "#DE7E00" + origin_tech = "materials=5;programming=4;biotech=4" /obj/item/cybernetic_implant/brain/anti_drop/function() action_button_name = "Toggle Anti-Drop" @@ -187,6 +195,8 @@ r_hand_obj = null /obj/item/cybernetic_implant/brain/anti_drop/emp_act(severity) + if(!owner) + return var/range = severity ? 10 : 5 var/atom/A var/obj/item/L_item = owner.l_hand @@ -213,6 +223,7 @@ name = "CNS Rebooter implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." implant_color = "#FFFF00" + origin_tech = "materials=6;programming=4;biotech=5" /obj/item/cybernetic_implant/brain/anti_stun/function() SSobj.processing |= src @@ -231,6 +242,132 @@ owner.weakened = STUN_SET_AMOUNT /obj/item/cybernetic_implant/brain/anti_stun/emp_act(severity) + if(!owner) + return SSobj.processing.Remove(src) spawn(..() * 10) - SSobj.processing |= src \ No newline at end of file + SSobj.processing |= src + + +//[[[[CHEST]]]] + +/obj/item/cybernetic_implant/chest + name = "cybernetic torso implant" + desc = "implants for the organs in your torso" + icon_state = "chest_implant" + +/obj/item/cybernetic_implant/chest/New() + var/icon/overlay = new /icon('icons/obj/surgery.dmi',"chest_implant_overlay") + overlay.ColorTone(implant_color) + overlays |= overlay + ..() + +/obj/item/cybernetic_implant/chest/nutriment + name = "Nutriment pump implant" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." + icon_state = "chest_implant" + implant_color = "#F968B5" + var/hunger_threshold = NUTRITION_LEVEL_STARVING + var/synthesizing = 0 + var/nutriment_amount = 30 + var/poison_amount = 5 + origin_tech = "materials=5;programming=3;biotech=4" + +/obj/item/cybernetic_implant/chest/nutriment/function() + SSobj.processing |= src + +/obj/item/cybernetic_implant/chest/nutriment/process() + if(synthesizing) + return + if(!owner) + SSobj.processing.Remove(src) + qdel(src) + return + if(owner.stat == DEAD) + return + + if(owner.nutrition <= hunger_threshold) + synthesizing = 1 + spawn(50) + owner << "You feel less hungry..." + owner.nutrition += nutriment_amount + synthesizing = 0 + +/obj/item/cybernetic_implant/chest/nutriment/plus + name = "Nutriment pump implant PLUS" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." + icon_state = "chest_implant" + implant_color = "#FF0044" + hunger_threshold = NUTRITION_LEVEL_HUNGRY + nutriment_amount = 50 + poison_amount = 10 + origin_tech = "materials=5;programming=3;biotech=5" + +/obj/item/cybernetic_implant/chest/nutriment/emp_act(severity) + if(!owner) + return + owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning + owner << "You feel like your insides are burning." + +/obj/item/cybernetic_implant/chest/heart/reviver + name = "Reviver implant" + desc = "This implant will automatically deliver a therapeutic dose of electrical energy to your heart if it ever stops beating, and inject nanites into your bloodstream. A second chance!" + icon_state = "chest_implant" + implant_color = "#FF8000" + var/defibrillating = 0 + var/recharge_time = 0 + origin_tech = "materials=7;programming=3;biotech=4" + +/obj/item/cybernetic_implant/chest/heart/reviver/function() + if(istype(owner,/mob/living/carbon/human)) + recharge_time = world.time + 2000 + SSobj.processing |= src + +/obj/item/cybernetic_implant/chest/heart/reviver/process() + if(defibrillating) + return + if(!owner) + SSobj.processing.Remove(src) + qdel(src) + return + if(world.time < recharge_time) + return + if(owner.stat != DEAD) + return + + defibrillating = 1 + spawn(600) + if(owner.stat == DEAD) + owner.visible_message("[owner]'s body convulses by itself.") + playsound(owner, "bodyfall", 50, 1) + playsound(owner, 'sound/machines/defib_zap.ogg', 50, 1, -1) + dead_mob_list -= owner + living_mob_list |= list(owner) + owner.stat = UNCONSCIOUS + owner.reagents.add_reagent("nanites",10) + var/mob/living/carbon/human/H = owner + var/amount = BLOOD_VOLUME_OKAY - H.vessel.total_volume + H.vessel.add_reagent("blood", amount) + H.vessel.update_total() + owner.heart_attack = 0 + owner.emote("gasp") + add_logs(owner, owner, "revived", object="defibrillator implant") + recharge_time = world.time + 20000 + defibrillating = 0 + +/obj/item/cybernetic_implant/chest/heart/reviver/emp_act(severity) + if(!owner) + return + if(recharge_time < world.time) + recharge_time = world.time + (2000 / severity) + else + recharge_time += 2000 / severity + + if(prob(60/severity)) + playsound(owner, 'sound/machines/defib_saftyOff.ogg', 50, 1, -1) + spawn(30) + playsound(owner, 'sound/machines/defib_zap.ogg', 50, 1, -1) + owner.heart_attack = 1 + if(owner.stat == CONSCIOUS) + owner.Weaken(5) + owner.visible_message("[owner] clutches at their chest as if their heart stopped!") \ No newline at end of file diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index f4509701ac0..19d5eca182c 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -86,6 +86,28 @@ user.visible_message("[user] screws up!") return 0 +/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(locate(/datum/surgery_step/saw) in surgery.steps) + var/limb_type + switch(target_zone) + if("head") + limb_type = /obj/item/organ/limb/head + if("chest") + limb_type = /obj/item/organ/limb/chest + if("l_arm") + limb_type = /obj/item/organ/limb/l_arm + if("r_arm") + limb_type = /obj/item/organ/limb/r_arm + if("l_leg") + limb_type = /obj/item/organ/limb/l_leg + if("r_leg") + limb_type = /obj/item/organ/limb/r_leg + else + return + var/obj/item/organ/limb/limb = target.getlimb(limb_type) + if(limb) + limb.heal_damage(45,0,0) + return ..() /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) return 1 diff --git a/html/changelogs/xxalpha-cyberplus.yml b/html/changelogs/xxalpha-cyberplus.yml new file mode 100644 index 00000000000..e66634d5587 --- /dev/null +++ b/html/changelogs/xxalpha-cyberplus.yml @@ -0,0 +1,10 @@ +author: xxalpha + +delete-after: True + +changes: + - rscadd: "Added Nutriment Pump, Nutriment Pump Plus and Reviver implants." + - tweak: "Added origin technologies to all implants". + - tweak: "The following implants are now much harder to obtain: X-ray, Thermals, Anti-Stun, Nutriment Pump Plus, Reviver." + - tweak: "Cauterizing a surgery wound will now heal some of the damage done by the bonesaw if it was used as part of the same surgery." + - tweak: "Added ability for Medical HUDs to detect cybernetic implants in humans." \ No newline at end of file diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 93ebade829d..aa5259be1aa 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ