From a65867ca69314b68eb02c86b1eb3651a37b3cca5 Mon Sep 17 00:00:00 2001 From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com> Date: Wed, 30 Mar 2022 13:04:06 -0400 Subject: [PATCH 1/9] Initial commit --- baystation12.dme | 3 +- code/__defines/damage_organs.dm | 1 + code/__defines/mobs.dm | 25 +- code/modules/augment/active.dm | 17 +- code/modules/augment/active/armblades.dm | 66 +++-- code/modules/augment/active/circuit.dm | 45 ++- code/modules/augment/active/hudimplants.dm | 47 +++- code/modules/augment/active/polytool.dm | 70 ++--- .../augment/active/tool/engineering.dm | 8 - code/modules/augment/active/tool/surgical.dm | 8 +- code/modules/augment/augment.dm | 262 ++++++++++++++---- code/modules/augment/item.dm | 119 ++++++++ code/modules/augment/passive/armor.dm | 5 +- code/modules/augment/passive/boost.dm | 100 ++++--- code/modules/augment/passive/boost/muscle.dm | 71 +++-- code/modules/augment/passive/nanoaura.dm | 85 +++--- code/modules/augment/simple.dm | 73 ----- .../preference_setup/loadout/loadout.dm | 9 +- .../organs/external/_external_damage.dm | 4 +- code/modules/organs/external/diagnostics.dm | 4 +- code/modules/organs/organ.dm | 7 + .../research/designs/designs_mechfab.dm | 6 +- code/modules/surgery/limb_reattach.dm | 9 + code/modules/surgery/organs_internal.dm | 6 +- code/modules/surgery/robotics.dm | 2 +- maps/torch/loadout/loadout_augments.dm | 5 +- 26 files changed, 663 insertions(+), 394 deletions(-) create mode 100644 code/modules/augment/item.dm delete mode 100644 code/modules/augment/simple.dm diff --git a/baystation12.dme b/baystation12.dme index 4511f4c8b6f..996133f9bc4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1453,9 +1453,10 @@ #include "code\modules\atmospherics\components\unary\vent_scrubber.dm" #include "code\modules\augment\active.dm" #include "code\modules\augment\augment.dm" -#include "code\modules\augment\simple.dm" +#include "code\modules\augment\item.dm" #include "code\modules\augment\active\armblades.dm" #include "code\modules\augment\active\circuit.dm" +#include "code\modules\augment\active\hudimplants.dm" #include "code\modules\augment\active\polytool.dm" #include "code\modules\augment\active\tool\engineering.dm" #include "code\modules\augment\active\tool\surgical.dm" diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 9edaec362ba..59e2d62378c 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -50,6 +50,7 @@ #define ORGAN_ROBOTIC (1<<11) // The organ is robotic. Changes numerous behaviors, search BP_IS_ROBOTIC for checks. #define ORGAN_BRITTLE (1<<12) // The organ takes additional blunt damage. If robotic, cannot be repaired through normal means. #define ORGAN_CRYSTAL (1<<13) // The organ does not suffer laser damage, but shatters on droplimb. +#define ORGAN_CONFIGURE (1<<14) // The organ has an extra configuration step for surgery that it handles itself. // Organ flag defines. #define ORGAN_FLAG_CAN_AMPUTATE (1<<0) // The organ can be amputated. diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 4d26bdaf0ee..75ca3c16a69 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -229,9 +229,30 @@ #define BP_AUGMENT_CHEST_ACTIVE "active chest augment" #define BP_AUGMENT_HEAD "head augment" +/** +* Augment Slots +* Flags used by /obj/item/organ/internal/augment/var/augment_slots +* Augment slots is used to control which body parts an augment may be installed into +*/ + +//Augment slots +#define AUGMENT_ARM 0x1 ///The augment can be installed in arms +#define AUGMENT_HAND 0x2 ///The augment can be installed in hands +#define AUGMENT_LEG 0x4 ///The augment can be installed in legs +#define AUGMENT_FOOT 0x8 ///The augment can be installed in legs +#define AUGMENT_CHEST 0x10 ///The augment can be installed in the chest +#define AUGMENT_GROIN 0x20 ///The augment can be installed in the lower body +#define AUGMENT_HEAD 0x40 ///The augment can be installed in the head +#define AUGMENT_ARMOR 0x80 ///The augment can be installed externally +#define AUGMENT_FLUFF 0x100 ///The augment can be installed in a secondary head slot + + //Augment flags -#define AUGMENTATION_MECHANIC 1 -#define AUGMENTATION_ORGANIC 2 +#define AUGMENT_MECHANICAL 0x1 ///The augment can be installed in mechanical organs +#define AUGMENT_BIOLOGICAL 0x2 ///The augment can be installed in biological organs +#define AUGMENT_CRYSTALINE 0x4 ///The augment can be installed in crystaline organs +#define AUGMENT_SCANNABLE 0x10 ///The augment is visible on body scanner results +#define AUGMENT_INSPECTABLE 0x20 ///The augment is visible via grab inspection // Limbs. #define BP_L_FOOT "l_foot" diff --git a/code/modules/augment/active.dm b/code/modules/augment/active.dm index c8be5bf6110..847999137f9 100644 --- a/code/modules/augment/active.dm +++ b/code/modules/augment/active.dm @@ -3,9 +3,9 @@ action_button_name = "Activate" var/obj/item/organ/external/limb + /obj/item/organ/internal/augment/active/proc/activate() -//Give verbs on install /obj/item/organ/internal/augment/active/onInstall() limb = owner.get_organ(parent_organ) @@ -13,26 +13,23 @@ limb = null /obj/item/organ/internal/augment/active/proc/can_activate() - if(!owner || owner.incapacitated() || !is_usable()) + if (!owner || owner.incapacitated() || !is_usable()) to_chat(owner, SPAN_WARNING("You can't do that now!")) return FALSE - return TRUE - /obj/item/organ/internal/augment/active/attack_self() . = ..() - if(.) + if (.) activate() -//Need to change icon? /obj/item/organ/internal/augment/active/refresh_action_button() . = ..() - if(.) + if (.) action.button_icon_state = icon_state - if(action.button) action.button.UpdateIcon() - + if (action.button) + action.button.UpdateIcon() /obj/item/organ/internal/augment/active/Destroy() limb = null - . = ..() \ No newline at end of file + . = ..() diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm index 97361ea8099..a17791c6318 100644 --- a/code/modules/augment/active/armblades.dm +++ b/code/modules/augment/active/armblades.dm @@ -1,41 +1,67 @@ -/obj/item/weapon/material/armblade +/obj/item/material/armblade icon_state = "armblade" item_state = null name = "armblade" icon = 'icons/obj/augment.dmi' - applies_material_colour = 0 desc = "A handy utility blade for the discerning augmentee. Warranty void if used for cutting." base_parry_chance = 30 - unbreakable = 1 - force_divisor = 0.2 - sharp = 1 - edge = 1 + unacidable = TRUE + sharp = TRUE + edge = TRUE attack_verb = list("stabbed", "sliced", "cut") - applies_material_colour = 0 -/obj/item/organ/internal/augment/active/simple/armblade + +/obj/item/organ/internal/augment/active/item/armblade name = "embedded blade" desc = "A sturdy housing for a steel utility blade." action_button_name = "Deploy blade" icon_state = "armblade" - allowed_organs = list(BP_AUGMENT_R_ARM, BP_AUGMENT_L_ARM) - holding_type = /obj/item/weapon/material/armblade - //Limited to robolimbs - augment_flags = AUGMENTATION_MECHANIC + augment_slots = AUGMENT_ARM + item = /obj/item/material/armblade + augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE + -/obj/item/weapon/material/armblade/claws +/obj/item/material/armblade/claws icon_state = "wolverine" name = "combat claws" desc = "These do not grow back." - force_divisor = 0.3 + base_parry_chance = 40 + -//Alternate look -/obj/item/organ/internal/augment/active/simple/wolverine +/obj/item/organ/internal/augment/active/item/wolverine name = "cyberclaws" desc = "An unusual type of cybernetic weaponry, these sharp blades are bound to turn heads." action_button_name = "Deploy claws" icon_state = "wolverine" - allowed_organs = list(BP_AUGMENT_R_HAND, BP_AUGMENT_L_HAND) - holding_type = /obj/item/weapon/material/armblade/claws - //Limited to robolimbs - augment_flags = AUGMENTATION_MECHANIC + augment_slots = AUGMENT_HAND + item = /obj/item/material/armblade/claws + augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE + + +/// Traitor version - no parry chance but good damage, and compatible with organic limbs +/obj/item/organ/internal/augment/active/item/wrist_blade + name = "concealed wrist blade" + desc = "A concealed sheath made from bio-compatible cloth, shaped for a thin blade." + action_button_name = "Deploy blade" + icon_state = "armblade" + augment_slots = AUGMENT_ARM + item = /obj/item/material/armblade/wrist + origin_tech = list(TECH_COMBAT = 3, TECH_ESOTERIC = 4) + deploy_sound = 'sound/effects/holster/sheathout.ogg' + retract_sound = 'sound/effects/holster/sheathin.ogg' + augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL + + +/obj/item/material/armblade/wrist + name = "wrist blade" + desc = "A thin and very sharp folding blade specially made for combat, made from a specialized alloy that prevents all that nasty blood and viscera from sticking to it. Its light weight allows for rapid slashing attacks." + icon_state = "wristblade" + item_state = "wristblade" + base_parry_chance = 0 + + /// SMALL prevents dismembering limbs - only hands & feet + w_class = ITEM_SIZE_SMALL + + +/obj/item/material/armblade/wrist/add_blood(mob/living/carbon/human/M) + return FALSE diff --git a/code/modules/augment/active/circuit.dm b/code/modules/augment/active/circuit.dm index 70e6130dc53..f85160b94ed 100644 --- a/code/modules/augment/active/circuit.dm +++ b/code/modules/augment/active/circuit.dm @@ -1,38 +1,29 @@ -/obj/item/organ/internal/augment/active/simple/circuit +/obj/item/organ/internal/augment/active/item/circuit name = "integrated circuit frame" action_button_name = "Activate Circuit" icon_state = "circuit" - allowed_organs = list(BP_AUGMENT_R_ARM, BP_AUGMENT_L_ARM) - holding_type = null //We must get the holding item externally - //Limited to robolimbs - augment_flags = AUGMENTATION_MECHANIC - desc = "A DIY modular assembly, courtesy of Xion Industrial. Circuitry not included" + augment_slots = AUGMENT_ARM + augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE + desc = "A DIY modular assembly, courtesy of Xion Industrial. Circuitry not included." -/obj/item/organ/internal/augment/active/simple/circuit/left - allowed_organs = list(BP_AUGMENT_L_ARM) - -/obj/item/organ/internal/augment/active/simple/circuit/right - allowed_organs = list(BP_AUGMENT_R_ARM) - -/obj/item/organ/internal/augment/active/simple/circuit/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(isCrowbar(W)) - //Remove internal circuit - if(holding) - holding.canremove = 1 - holding.dropInto(loc) - to_chat(user, SPAN_NOTICE("You take out \the [holding].")) - holding = null +/obj/item/organ/internal/augment/active/item/circuit/attackby(obj/item/I, mob/user) + if (isCrowbar(I)) + if (item) + item.canremove = TRUE + item.dropInto(loc) + to_chat(user, SPAN_NOTICE("You take out \the [item].")) + item = null playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) - else to_chat(user, SPAN_WARNING("The augment is empty!")) + else + to_chat(user, SPAN_WARNING("The augment is empty!")) return - if(istype(W, /obj/item/device/electronic_assembly/augment)) - if(holding) + if (istype(I, /obj/item/device/electronic_assembly/augment)) + if (item) to_chat(user, SPAN_WARNING("There's already an assembly in there.")) - else if(user.unEquip(W, src)) - holding = W - holding.canremove = 0 + else if (user.unEquip(I, src)) + item = I + item.canremove = FALSE playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) return - ..() \ No newline at end of file diff --git a/code/modules/augment/active/hudimplants.dm b/code/modules/augment/active/hudimplants.dm index eb967fecb0b..aa203863fba 100644 --- a/code/modules/augment/active/hudimplants.dm +++ b/code/modules/augment/active/hudimplants.dm @@ -3,24 +3,29 @@ desc = "A small implantable heads-up display." icon_state = "eye" action_button_name = "Toggle HUD" - allowed_organs = list(BP_AUGMENT_HEAD) + augment_slots = AUGMENT_HEAD var/list/hud_type = list(HUD_MEDICAL, HUD_SECURITY) var/active = FALSE + /obj/item/organ/internal/augment/active/hud/Process() ..() if (!owner) return if (active) - if (hud_type == HUD_MEDICAL) - req_access = list(access_medical) - if (allowed(owner)) - process_med_hud(owner, 1) - else if (hud_type == HUD_SECURITY) - req_access = list(access_security) - if (allowed(owner)) - process_sec_hud(owner, 1) + switch(hud_type) + if (HUD_MEDICAL) + req_access = list(access_medical) + if (allowed(owner)) + process_med_hud(owner, 1) + if (HUD_SECURITY) + req_access = list(access_security) + if (allowed(owner)) + process_sec_hud(owner, 1) + if (HUD_JANITOR) + process_jani_hud(owner) + /obj/item/organ/internal/augment/active/hud/emp_act(severity) if (istype(src.loc, /mob/living/carbon/human)) @@ -32,18 +37,36 @@ if (active) active = FALSE + /obj/item/organ/internal/augment/active/hud/activate() if (!can_activate()) return active = !active + to_chat(owner, SPAN_NOTICE("You [active ? "enable" : "disable"] \the [src].")) + /obj/item/organ/internal/augment/active/hud/health name = "integrated health HUD" - desc = "The Vey-Med H-27 is an implantable HUD, designed to interface directly with the user's optic nerve and display information about patient vitals." + desc = "The Vey-Med H-27 is an implantable HUD, designed to interface with the user's optic nerve and display information about patient vitals." icon_state = "eye_medical" hud_type = HUD_MEDICAL + /obj/item/organ/internal/augment/active/hud/security name = "integrated security HUD" - desc = "The Hephaestus Industries C-VSR is an implantable HUD, designed to interface directly with the user's optic nerve and local databases to display security information." - hud_type = HUD_SECURITY \ No newline at end of file + desc = "The Hephaestus Industries C-VSR is an implantable HUD, designed to interface with the user's optic nerve and local databases to display security information." + hud_type = HUD_SECURITY + + +/obj/item/organ/internal/augment/active/hud/janitor + name = "integrated filth HUD" + desc = "An implantable HUD based on the wearable janitorial version, designed to interface with the user's optic nerve and display information about nearby messes." + icon_state = "eye_janitor" + hud_type = HUD_JANITOR + + +/obj/item/organ/internal/augment/active/hud/science + name = "integrated sciHUD" + desc = "An implantable HUD fitted with a portable analyzer capable of determining the research potential of a visible item or the components of a machine." + icon_state = "eye_science" + hud_type = HUD_SCIENCE \ No newline at end of file diff --git a/code/modules/augment/active/polytool.dm b/code/modules/augment/active/polytool.dm index 79409b5a69f..ddd8d81876e 100644 --- a/code/modules/augment/active/polytool.dm +++ b/code/modules/augment/active/polytool.dm @@ -2,57 +2,61 @@ name = "Polytool embedded module" action_button_name = "Deploy Tool" icon_state = "multitool" - allowed_organs = list(BP_AUGMENT_R_HAND, BP_AUGMENT_L_HAND) + augment_slots = AUGMENT_HAND var/list/items = list() var/list/paths = list() //We may lose them - augment_flags = AUGMENTATION_MECHANIC + augment_flags = AUGMENT_MECHANICAL + /obj/item/organ/internal/augment/active/polytool/Initialize() . = ..() - for(var/path in paths) + for (var/path in paths) var/obj/item/I = new path (src) I.canremove = FALSE items += I -/obj/item/organ/internal/augment/active/polytool/proc/holding_dropped(var/obj/item/I) - //Stop caring - GLOB.item_unequipped_event.unregister(I, src) - - if(I.loc != src) //something went wrong and is no longer attached/ it broke - I.canremove = TRUE /obj/item/organ/internal/augment/active/polytool/Destroy() QDEL_NULL_LIST(items) . = ..() + +/obj/item/organ/internal/augment/active/polytool/proc/holding_dropped(obj/item/I) + GLOB.item_unequipped_event.unregister(I, src) + if (I.loc != src) + I.canremove = TRUE + + /obj/item/organ/internal/augment/active/polytool/activate() - if(!can_activate()) + if (!can_activate()) return var/slot = null - - if(limb.organ_tag in list(BP_L_ARM, BP_L_HAND)) + if (limb.organ_tag in list(BP_L_ARM, BP_L_HAND)) slot = slot_l_hand - else if(limb.organ_tag in list(BP_R_ARM, BP_R_HAND)) + else if (limb.organ_tag in list(BP_R_ARM, BP_R_HAND)) slot = slot_r_hand - var/obj/I = slot == slot_l_hand ? owner.l_hand : owner.r_hand - - var/list/options = list() - for(var/obj/item/IT in items - I) - options[IT] = IT.appearance - var/obj/item = RADIAL_INPUT(owner, options) - if(I) - if(!(I in items)) - to_chat(owner, SPAN_WARNING("You can't extend your [item], [I] is in the way!")) - return - if(!owner.drop_from_inventory(I, src)) - to_chat(owner, SPAN_WARNING("You are unable to retract [I] into your [limb.name]!")) + if (I) + if (is_type_in_list(I,paths) && !(I.type in items)) //We don't want several of same but you can replace parts whenever + if (!owner.drop_from_inventory(I, src)) + to_chat(owner, "\the [I] fails to retract.") + return + items += I + owner.visible_message( + SPAN_WARNING("[owner] retracts \his [I] into [limb]."), + SPAN_NOTICE("You retract your [I] into [limb].") + ) + else + to_chat(owner, SPAN_WARNING("You must drop [I] before tool can be extend.")) + else + var/obj/item = input(owner, "Select item for deploy") as null|anything in src + if (!item || !(src in owner.internal_organs)) return - owner.visible_message(SPAN_WARNING("[owner] retracts \his [I] into \his [limb.name]."), SPAN_NOTICE("You retract your [I] into your [limb.name].")) - - if(owner.equip_to_slot_if_possible(item, slot)) - GLOB.item_unequipped_event.register(item, src, /obj/item/organ/internal/augment/active/polytool/proc/holding_dropped) - owner.visible_message( - SPAN_WARNING("[owner] extends \his [item.name] from \his [limb.name]."), - SPAN_NOTICE("You extend your [item.name] from your [limb.name].") - ) \ No newline at end of file + if (owner.equip_to_slot_if_possible(item, slot)) + items -= item + //Keep track of it, make sure it returns + GLOB.item_unequipped_event.register(item, src, /obj/item/organ/internal/augment/active/polytool/proc/holding_dropped) + owner.visible_message( + SPAN_WARNING("[owner] extends \his [item.name] from [limb]."), + SPAN_NOTICE("You extend your [item.name] from [limb].") + ) diff --git a/code/modules/augment/active/tool/engineering.dm b/code/modules/augment/active/tool/engineering.dm index 209c68d5cdc..818b9cbae71 100644 --- a/code/modules/augment/active/tool/engineering.dm +++ b/code/modules/augment/active/tool/engineering.dm @@ -1,5 +1,3 @@ - - /obj/item/organ/internal/augment/active/polytool/engineer name = "\improper Engineering toolset" action_button_name = "Deploy Engineering Tool" @@ -12,12 +10,6 @@ /obj/item/weapon/wirecutters/finger, /obj/item/device/multitool/finger ) -//This is a hack, but i'm too fucking lazy to deal with it. -/obj/item/organ/internal/augment/active/polytool/engineer/left - allowed_organs = list(BP_AUGMENT_L_ARM) - -/obj/item/organ/internal/augment/active/polytool/engineer/right - allowed_organs = list(BP_AUGMENT_R_ARM) /obj/item/weapon/weldingtool/finger name = "digital welder" diff --git a/code/modules/augment/active/tool/surgical.dm b/code/modules/augment/active/tool/surgical.dm index e3628a1d221..dc6c81c2749 100644 --- a/code/modules/augment/active/tool/surgical.dm +++ b/code/modules/augment/active/tool/surgical.dm @@ -11,10 +11,4 @@ /obj/item/weapon/retractor, /obj/item/weapon/scalpel, /obj/item/weapon/surgicaldrill - ) - -/obj/item/organ/internal/augment/active/polytool/surgical/left - allowed_organs = list(BP_AUGMENT_L_ARM) - -/obj/item/organ/internal/augment/active/polytool/surgical/right - allowed_organs = list(BP_AUGMENT_R_ARM) \ No newline at end of file + ) \ No newline at end of file diff --git a/code/modules/augment/augment.dm b/code/modules/augment/augment.dm index 54cc3811a6d..ac720c1abcd 100644 --- a/code/modules/augment/augment.dm +++ b/code/modules/augment/augment.dm @@ -1,83 +1,223 @@ +/** +* Augments +* Extra organs that can be embedded to provide behaviors and flavor +*/ /obj/item/organ/internal/augment name = "embedded augment" - desc = "Embedded augment." icon = 'icons/obj/augment.dmi' - //By default these fit on both flesh and robotic organs and are robotic - status = ORGAN_ROBOTIC - var/augment_flags = AUGMENTATION_MECHANIC | AUGMENTATION_ORGANIC - var/list/allowed_organs = list(BP_AUGMENT_R_ARM, BP_AUGMENT_L_ARM) + status = ORGAN_ROBOTIC | ORGAN_CONFIGURE default_action_type = /datum/action/item_action/organ/augment - var/descriptor = "" - var/known = TRUE + var/augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE + var/augment_slots = 0 -/obj/item/organ/internal/augment/Initialize() - . = ..() - organ_tag = pick(allowed_organs) - update_parent_organ() -//General expectation is onInstall and onRemoved are overwritten to add effects to augmentee -/obj/item/organ/internal/augment/replaced(var/mob/living/carbon/human/target) - if(..() && istype(owner)) +#define ORGAN_STYLE ( \ + (organ.status & ORGAN_ROBOTIC) ? 1 \ +: (organ.status & ORGAN_CRYSTAL) ? 2 \ +: 0 \ +) + +#define ORGAN_STYLE_OK ( \ + style == 0 && (augment_flags & AUGMENT_BIOLOGICAL) \ +|| style == 1 && (augment_flags & AUGMENT_MECHANICAL) \ +|| style == 2 && (augment_flags & AUGMENT_CRYSTALINE) \ +) + +/obj/item/organ/internal/augment/proc/get_valid_parent_organ(mob/living/carbon/subject) + if (!istype(subject)) + return + var/style + var/obj/item/organ/external/organ + var/list/organs = subject.organs_by_name + if ((augment_slots & AUGMENT_CHEST) && !organs["[BP_CHEST]_aug"] && (organ = organs[BP_CHEST])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if ((augment_slots & AUGMENT_ARMOR) && !organs["[BP_CHEST]_aug_armor"] && (organ = organs[BP_CHEST])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if ((augment_slots & AUGMENT_GROIN) && !organs["[BP_GROIN]_aug"] && (organ = organs[BP_GROIN])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if ((augment_slots & AUGMENT_HEAD) && !organs["[BP_HEAD]_aug"] && (organ = organs[BP_HEAD])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if ((augment_slots & AUGMENT_FLUFF) && !organs["[BP_HEAD]_aug_fluff"] && (organ = organs[BP_HEAD])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (augment_slots & AUGMENT_ARM) + if (!organs["[BP_L_ARM]_aug"] && (organ = organs[BP_L_ARM])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (!organs["[BP_R_ARM]_aug"] && (organ = organs[BP_R_ARM])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (augment_slots & AUGMENT_HAND) + if (!organs["[BP_L_HAND]_aug"] && (organ = organs[BP_L_HAND])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (!organs["[BP_R_HAND]_aug"] && (organ = organs[BP_R_HAND])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (augment_slots & AUGMENT_LEG) + if (!organs["[BP_L_LEG]_aug"] && (organ = organs[BP_L_LEG])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (!organs["[BP_R_LEG]_aug"] && (organ = organs[BP_R_LEG])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (augment_slots & AUGMENT_FOOT) + if (!organs["[BP_L_FOOT]_aug"] && (organ = organs[BP_L_FOOT])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + if (!organs["[BP_R_FOOT]_aug"] && (organ = organs[BP_R_FOOT])) + style = ORGAN_STYLE + if (ORGAN_STYLE_OK) + return organ + +#undef ORGAN_STYLE_OK +#undef ORGAN_STYLE + + +/obj/item/organ/internal/augment/surgery_configure(mob/living/user, mob/living/carbon/human/target, obj/item/organ/parent, obj/item/tool, decl/surgery_step/action) + var/found + switch (parent?.organ_tag) + if (null) + found = FALSE + if (BP_L_ARM, BP_R_ARM) + found = augment_slots & AUGMENT_ARM + if (BP_L_HAND, BP_R_HAND) + found = augment_slots & AUGMENT_HAND + if (BP_L_LEG, BP_R_LEG) + found = augment_slots & AUGMENT_LEG + if (BP_L_FOOT, BP_R_FOOT) + found = augment_slots & AUGMENT_FOOT + if (BP_CHEST) + found = augment_slots & (AUGMENT_CHEST | AUGMENT_ARMOR) + if (BP_GROIN) + found = augment_slots & AUGMENT_GROIN + if (BP_HEAD) + found = augment_slots & (AUGMENT_HEAD | AUGMENT_FLUFF) + if (!found) + to_chat(user, SPAN_WARNING("\The [src] can't be installed in \the [parent].")) + parent_organ = null + organ_tag = null + return 1 + parent_organ = parent.organ_tag + if (found == AUGMENT_ARMOR) + organ_tag = "[parent_organ]_aug_armor" + if (found == AUGMENT_FLUFF) + organ_tag = "[parent_organ]_aug_fluff" + else + organ_tag = "[parent_organ]_aug" + + +/obj/item/organ/internal/augment/replaced(mob/living/carbon/human/target) + if (..() && istype(owner)) onInstall() -/obj/item/organ/internal/augment/proc/onInstall() - return -/obj/item/organ/internal/augment/removed(var/mob/living/user, var/drop_organ=1) +/obj/item/organ/internal/augment/removed(mob/living/user, drop_organ = TRUE) onRemove() ..() + +/// Virtual for removing augment effects from owner /obj/item/organ/internal/augment/proc/onRemove() return -/obj/item/organ/internal/augment/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(isScrewdriver(W) && allowed_organs.len > 1) - //Here we can adjust location for implants that allow multiple slots - organ_tag = show_radial_menu(user, src, allowed_organs) - update_parent_organ() - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - return - ..() +/// Virtual for adding augment effects to owner when surgically added +/obj/item/organ/internal/augment/proc/onInstall() + return -/obj/item/organ/internal/augment/proc/update_parent_organ() - //This tries to match a parent organ to an augment slot - //This is intended to match the possible positions to a parent organ - - if(organ_tag == BP_AUGMENT_L_LEG) - parent_organ = BP_L_LEG - descriptor = "left leg." - else if(organ_tag == BP_AUGMENT_R_LEG) - parent_organ = BP_R_LEG - descriptor = "right leg." - else if(organ_tag == BP_AUGMENT_L_HAND) - parent_organ = BP_L_HAND - descriptor = "left hand." - else if(organ_tag == BP_AUGMENT_R_HAND) - parent_organ = BP_R_HAND - descriptor = "right hand." - else if(organ_tag == BP_AUGMENT_L_ARM) - parent_organ = BP_L_ARM - descriptor = "left arm." - else if(organ_tag == BP_AUGMENT_R_ARM) - parent_organ = BP_R_ARM - descriptor = "right arm." - else if(organ_tag == BP_AUGMENT_HEAD) - parent_organ = BP_HEAD - descriptor = "head." - else if(organ_tag == BP_AUGMENT_CHEST_ACTIVE || organ_tag == BP_AUGMENT_CHEST_ARMOUR) - parent_organ = BP_CHEST - descriptor = "chest." + +/// Virtual for adding additional behavior when augment is already present at owner instantiation +/obj/item/organ/internal/augment/proc/onRoundstart() + return /obj/item/organ/internal/augment/examine(mob/user, distance) . = ..() - if(distance <= 1) - to_chat(user, "It is configured to be attached to the [descriptor].") - if(augment_flags & AUGMENTATION_MECHANIC && augment_flags & AUGMENTATION_ORGANIC) - to_chat(user, "It can interface with both prosthetic and fleshy organs.") + var/level + if (isobserver(user)) + level = 2 + else if (distance > 1) + return + else if (user.mind?.special_role) + level = 2 + else if (user.skill_check(SKILL_DEVICES, SKILL_PROF)) + level = 2 + else if (user.skill_check(SKILL_DEVICES, SKILL_ADEPT)) + level = 1 + if (!level) + return + var/list/attach_types = list() + if (augment_flags & AUGMENT_MECHANICAL) + attach_types += "mechanical" + if (augment_flags & AUGMENT_BIOLOGICAL) + attach_types += "biological" + if (augment_flags & AUGMENT_CRYSTALINE) + attach_types += "crystaline" + var/list/attach_parts = list() + if (augment_slots & (AUGMENT_CHEST|AUGMENT_ARMOR)) + attach_parts += "chests" + if (augment_slots & AUGMENT_GROIN) + attach_parts += "lower bodies" + if (augment_slots & (AUGMENT_HEAD|AUGMENT_FLUFF)) + attach_parts += "heads" + if (augment_slots & AUGMENT_ARM) + attach_parts += "arms" + if (augment_slots & AUGMENT_HAND) + attach_parts += "hands" + if (augment_slots & AUGMENT_LEG) + attach_parts += "legs" + if (augment_slots & AUGMENT_FOOT) + attach_parts += "feet" + var/message = "It can be installed in [english_list(attach_parts)] that are [english_list(attach_types)]." + if (level > 1) + var/list/discovery = list() + if (augment_flags & AUGMENT_SCANNABLE) + discovery += "scanners" + if (augment_flags & AUGMENT_INSPECTABLE) + discovery += "manual inspection" + if (discovery.len) + message += " It can be discovered by [english_list(discovery)]." else - if(augment_flags & AUGMENTATION_MECHANIC) - to_chat(user, "It can interface with prosthetic organs.") - else if(augment_flags & AUGMENTATION_ORGANIC) - to_chat(user, "It can interface with fleshy organs.") + message += " It is undetectable." + to_chat(user, message) + + +/datum/codex_entry/augment + display_name = "Implantable Augmentation" + associated_paths = list(/obj/item/organ/internal/augment) + lore_text = {"\ +
Augmentations are a broad category of devices that are added to the bodies of biological and \ + mechanical individuals in order to provide some function or benefit to the user. The most common \ + augmentations in humans are medical or otherwise corrective, but everything from weapons to reward \ + stimulators can be wired into the body one way or another, making many modern humans classic cyborgs.
\ +In non-biological entities "augmentations" are often simply normal body components that are not \ + already installed - but many of the same non-medical tools, utilities, and entertainment devices \ + are available.
\ + "} + mechanics_text = {"\ +Augmentations provide various (or no) functionality and are either passive or active. \ + A passive augmentation, so long as it is not too damaged, Just Works. An active augmentation can be \ + toggled on or off via its associated UI button, which appears on its owners screen once it has been \ + implanted.
\ +Some active augmentations, like tools and weapons, will try to place an item into (or take it from) \ + a hand or other inventory slot. You will need to keep those slots free in order to turn those \ + active augmentations on.
\ +
+ "}
diff --git a/code/modules/augment/item.dm b/code/modules/augment/item.dm
new file mode 100644
index 00000000000..34009e345de
--- /dev/null
+++ b/code/modules/augment/item.dm
@@ -0,0 +1,119 @@
+/**
+* Toggleable physical equipment augment
+* Specify a path on item to create on Initialize
+* Specify a slot or leave null to discover on install
+*/
+/obj/item/organ/internal/augment/active/item
+ var/deploy_sound = 'sound/items/helmet_close.ogg'
+ var/retract_sound = 'sound/items/helmet_open.ogg'
+ var/obj/item/item
+ var/slot
+
+
+/obj/item/organ/internal/augment/active/item/Initialize()
+ . = ..()
+ if (ispath(item))
+ item = new item (src)
+ item.canremove = FALSE
+
+
+/obj/item/organ/internal/augment/active/item/onInstall()
+ . = ..()
+ if (!slot)
+ switch (parent_organ)
+ if (BP_L_ARM, BP_L_HAND)
+ slot = slot_l_hand
+ if (BP_R_ARM, BP_R_HAND)
+ slot = slot_r_hand
+ if (BP_HEAD)
+ slot = slot_glasses
+ if (BP_CHEST)
+ slot = slot_wear_suit
+ if (BP_GROIN)
+ slot = slot_belt
+
+
+/obj/item/organ/internal/augment/active/item/onRemove()
+ retract(FALSE)
+ slot = initial(slot)
+ ..()
+
+
+/obj/item/organ/internal/augment/active/item/Destroy()
+ if (item)
+ GLOB.item_unequipped_event.unregister(item, src)
+ if (item.loc == src)
+ qdel(item)
+ else
+ item.canremove = TRUE
+ item = null
+ return ..()
+
+
+/obj/item/organ/internal/augment/active/item/proc/item_dropped()
+ GLOB.item_unequipped_event.unregister(item, src)
+ if (item.loc != src) // It fell off!
+ item.canremove = TRUE
+ item = null
+
+
+/obj/item/organ/internal/augment/active/item/proc/deploy(as_owner = TRUE)
+ if (!slot)
+ return
+ if (!item)
+ return
+ if (!owner.equip_to_slot_if_possible(item, slot))
+ return
+ GLOB.item_unequipped_event.register(item, src, /obj/item/organ/internal/augment/active/item/proc/item_dropped)
+ if (deploy_sound)
+ playsound(owner, deploy_sound, 30)
+ if (as_owner)
+ owner.visible_message(
+ SPAN_WARNING("\The [owner] extends \his [item.name] from \his [limb.name]."),
+ SPAN_NOTICE("You extend your [item.name] from your [limb.name].")
+ )
+ else
+ visible_message(SPAN_WARNING("\The [item.name] extend\s."))
+ return TRUE
+
+
+/obj/item/organ/internal/augment/active/item/proc/retract(as_owner = TRUE)
+ if (!item)
+ return
+ if (item.loc == src)
+ return
+ if (item.loc != owner)
+ return
+ var/mob/M = item.loc
+ if (!M.drop_from_inventory(item, src))
+ to_chat(owner, "\The [item.name] fails to retract.")
+ return
+ if (retract_sound)
+ playsound(owner, retract_sound, 30)
+ if (as_owner)
+ M.visible_message(
+ SPAN_WARNING("\The [M] retracts \his [item.name] into \his [limb.name]."),
+ SPAN_NOTICE("You retract your [item.name] into your [limb.name].")
+ )
+ else
+ visible_message(SPAN_WARNING("\The [item.name] retract\s."))
+ return TRUE
+
+
+/obj/item/organ/internal/augment/active/item/activate()
+ if (!can_activate())
+ return
+ if (item.loc == src)
+ deploy()
+ else
+ retract()
+ owner.update_action_buttons()
+
+
+/obj/item/organ/internal/augment/active/item/can_activate()
+ if (!..())
+ return FALSE
+ if (!item)
+ to_chat(owner, SPAN_WARNING("The device is damaged and fails to deploy."))
+ return FALSE
+ return TRUE
diff --git a/code/modules/augment/passive/armor.dm b/code/modules/augment/passive/armor.dm
index dad640529b8..d8695936dd7 100644
--- a/code/modules/augment/passive/armor.dm
+++ b/code/modules/augment/passive/armor.dm
@@ -1,7 +1,8 @@
/obj/item/organ/internal/augment/armor
name = "subdermal armor"
- allowed_organs = list(BP_AUGMENT_CHEST_ARMOUR)
+ augment_slots = AUGMENT_ARMOR
icon_state = "armor-chest"
desc = "A flexible composite mesh designed to prevent tearing and puncturing of underlying tissue."
+ augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE | AUGMENT_INSPECTABLE
var/brute_mult = 0.8
- var/burn_mult = 1
\ No newline at end of file
+ var/burn_mult = 1
diff --git a/code/modules/augment/passive/boost.dm b/code/modules/augment/passive/boost.dm
index f971f2a8077..57351c14bd0 100644
--- a/code/modules/augment/passive/boost.dm
+++ b/code/modules/augment/passive/boost.dm
@@ -1,15 +1,25 @@
-/datum/skill_buff/augment
- var/id
-
/obj/item/organ/internal/augment/boost
- var/list/buffs = list()//Which abilities does this impact?
- var/list/injury_debuffs = list()//If organ is damaged, should we reduce anything?
- var/buffpath = /datum/skill_buff/augment //if you use something else it should be a subtype or it will runtime
- var/active = 0 //mostly to control if we should remove buffs when we go
- var/debuffing = 0 //if we applied a debuff
- var/id //Unique Id assigned on new
icon_state = "booster"
- allowed_organs = list(BP_AUGMENT_HEAD)
+ augment_slots = AUGMENT_HEAD
+
+ /// Unique ID for collecting the right effect in skill handling
+ var/id
+
+ /// Which abilities does this impact?
+ var/list/buffs = list()
+
+ /// If organ is damaged, should we reduce anything?
+ var/list/injury_debuffs = list()
+
+ /// Only subtypes of /datum/skill_buff/augment
+ var/buffpath = /datum/skill_buff/augment
+
+ /// Mostly to control if we should remove buffs when we go
+ var/active = FALSE
+
+ /// If we applied a debuff
+ var/debuffing = FALSE
+
/obj/item/organ/internal/augment/boost/Initialize()
. = ..()
@@ -17,51 +27,59 @@
/obj/item/organ/internal/augment/boost/onInstall()
- if(buffs.len)
+ if (buffs.len)
var/datum/skill_buff/augment/A
A = owner.buff_skill(buffs, 0, buffpath)
- if(A && istype(A))
- active = 1
+ if (A && istype(A))
+ active = TRUE
A.id = id
+
/obj/item/organ/internal/augment/boost/onRemove()
- debuffing = 0
- if(!active)
+ debuffing = FALSE
+ if (!active)
return
- var/list/B = owner.fetch_buffs_of_type(buffpath, 0)
- for(var/datum/skill_buff/augment/D in B)
- if(D.id == id)
- D.remove()
- return
+ for(var/datum/skill_buff/augment/D as anything in owner.fetch_buffs_of_type(buffpath, 0))
+ if (D.id != id)
+ continue
+ D.remove()
+ return
+
-//Procs to set the negative skills and positive ones (This is once the initial setup has been done)
/obj/item/organ/internal/augment/boost/proc/debuff()
- if(!injury_debuffs ||!injury_debuffs.len)
- return 0
- var/list/B = owner.fetch_buffs_of_type(buffpath, 0)
- for(var/datum/skill_buff/augment/D in B)
- if(D.id == id)
- D.recalculate(injury_debuffs)
- debuffing = 1
- return 1
+ if (!length(injury_debuffs))
+ return FALSE
+ for(var/datum/skill_buff/augment/D as anything in owner.fetch_buffs_of_type(buffpath, 0))
+ if (D.id != id)
+ continue
+ D.recalculate(injury_debuffs)
+ debuffing = TRUE
+ return TRUE
+ return FALSE
+
/obj/item/organ/internal/augment/boost/proc/buff()
- if(!buffs || !buffs.len)
- return 0
- var/list/B = owner.fetch_buffs_of_type(buffpath, 0)
- for(var/datum/skill_buff/augment/D in B)
- if(D.id == id)
- D.recalculate(buffs)
- debuffing = 0
- return 1
+ if (!length(buffs))
+ return FALSE
+ for(var/datum/skill_buff/augment/D as anything in owner.fetch_buffs_of_type(buffpath, 0))
+ if (D.id != id)
+ continue
+ D.recalculate(buffs)
+ debuffing = FALSE
+ return TRUE
+ return FALSE
+
/obj/item/organ/internal/augment/boost/Process()
..()
- if(!owner)
+ if (!owner)
return
- if(is_broken() && !debuffing)
- debuff()
- else if(!is_broken() && debuffing)
+ if (!debuffing)
+ if (is_broken())
+ debuff()
+ else if (!is_broken())
buff()
+/datum/skill_buff/augment
+ var/id
diff --git a/code/modules/augment/passive/boost/muscle.dm b/code/modules/augment/passive/boost/muscle.dm
index d7f2a03e69c..34cf4b5646b 100644
--- a/code/modules/augment/passive/boost/muscle.dm
+++ b/code/modules/augment/passive/boost/muscle.dm
@@ -1,46 +1,57 @@
-//This one must do special handling because you need 2, so other than vars it doesn't share tht much
-/datum/skill_buff/augment/muscle
-
/obj/item/organ/internal/augment/boost/muscle
buffs = list(SKILL_HAULING = 1)
buffpath = /datum/skill_buff/augment/muscle
name = "mechanical muscles"
- allowed_organs = list(BP_AUGMENT_R_LEG, BP_AUGMENT_L_LEG)
+ augment_slots = AUGMENT_LEG
icon_state = "muscule"
- desc = "Nanofiber tendons powered by an array of actuators to help the wearer mantain speed even while encumbered. You may want to install these in pairs to see a result."
+ desc = "Nanofiber tendons powered by an array of actuators increase the speed and agility of the user. You may want to install these in pairs to see a result."
+ augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE | AUGMENT_INSPECTABLE
var/obj/item/organ/internal/augment/boost/muscle/other //we need two for these
-/obj/item/organ/internal/augment/boost/muscle/onInstall()
+/obj/item/organ/internal/augment/boost/muscle/proc/get_acrobatics_modifier()
+ if (!other?.is_broken() && !is_broken())
+ return 1
- //1.st Determine where we are and who we should be asking for guidance
- //we must be second to activate buff
- if(organ_tag == BP_AUGMENT_L_LEG)
- other = owner.internal_organs_by_name[BP_AUGMENT_R_LEG]
- else if(organ_tag == BP_AUGMENT_R_LEG)
- other = owner.internal_organs_by_name[BP_AUGMENT_L_LEG]
- if(other && istype(other))
- var/datum/skill_buff/augment/muscle/A
- A = owner.buff_skill(buffs, 0, buffpath)
- if(A && istype(A))
- active = 1
- other.active = 1
+
+/obj/item/organ/internal/augment/boost/muscle/onInstall()
+ if (parent_organ == BP_L_LEG)
+ other = owner.internal_organs_by_name["[BP_R_LEG]_aug"]
+ else if (parent_organ == BP_R_LEG)
+ other = owner.internal_organs_by_name["[BP_L_LEG]_aug"]
+ if (other && istype(other)) //we must be second to activate buff
+ var/succesful = TRUE
+ if (owner.get_skill_value(SKILL_HAULING) < SKILL_PROF)
+ succesful = FALSE
+ var/datum/skill_buff/augment/muscle/A
+ A = owner.buff_skill(buffs, 0, buffpath)
+ if (A && istype(A))
+ succesful = TRUE
+ A.id = id
+ if (succesful)
other.other = src
- A.id = id
+ other.active = TRUE
+ active = TRUE
+
/obj/item/organ/internal/augment/boost/muscle/onRemove()
- if(!active)
+ if (!active)
return
- var/list/B = owner.fetch_buffs_of_type(buffpath, 0)
- for(var/datum/skill_buff/augment/muscle/D in B)
- if(D.id == id)
- D.remove()
- if(other)
- other.active = 0
- other.other = null
- other = null
- return
+ for(var/datum/skill_buff/augment/D as anything in owner.fetch_buffs_of_type(buffpath, 0))
+ if (D.id != id)
+ continue
+ D.remove()
+ break
+ if (other)
+ other.active = FALSE
+ other.other = null
+ other = null
+ active = FALSE
+
/obj/item/organ/internal/augment/boost/muscle/Destroy()
. = ..()
- other = null //If somehow onRemove didn't handle it
+ other = null
+
+
+/datum/skill_buff/augment/muscle
diff --git a/code/modules/augment/passive/nanoaura.dm b/code/modules/augment/passive/nanoaura.dm
index b93ff73dd42..49cdf38a6a6 100644
--- a/code/modules/augment/passive/nanoaura.dm
+++ b/code/modules/augment/passive/nanoaura.dm
@@ -1,94 +1,73 @@
-//This handy augment protects you to a degree, keeping it online after critical damage however is bad
-
-/obj/aura/nanoaura
- name = "Nanoaura"
- var/obj/item/organ/internal/augment/active/nanounit/unit = null
- var/active = 0
-
-
-//The organ itself
-
/obj/item/organ/internal/augment/active/nanounit
name = "Nanite MCU"
- allowed_organs = list(BP_AUGMENT_CHEST_ACTIVE)
+ augment_slots = AUGMENT_CHEST
icon_state = "armor-chest"
desc = "Nanomachines, son."
action_button_name = "Toggle Nanomachines"
- var/obj/aura/nanoaura/aura = null
+ var/obj/aura/nanoaura/aura
var/charges = 4
- var/max_charges = 4
- var/list/memesounds = list('sound/effects/nanomachines/nanomachinesson.ogg', 'sound/effects/nanomachines/physicaltrauma.ogg')
- var/next_regen_time
- var/regen_delay = 5 MINUTES
- var/regen_amount = 1
-
-/obj/item/organ/internal/augment/active/nanounit/Initialize()
- . = ..()
- next_regen_time = world.time + regen_delay
- START_PROCESSING(SSobj, src)
-
-/obj/item/organ/internal/augment/active/nanounit/Destroy()
- STOP_PROCESSING(SSobj, src)
-/obj/item/organ/internal/augment/active/nanounit/Process()
- if(next_regen_time < world.time && (charges != max_charges))
- charges += regen_amount
- to_chat(owner, SPAN_NOTICE("Nanite MCU: Nanomaterial reprocessing complete - charge added. Current charges: [charges]."))
- next_regen_time = world.time + regen_delay
- ..()
/obj/item/organ/internal/augment/active/nanounit/onInstall()
- aura = new /obj/aura/nanoaura(owner, src)
+ aura = new /obj/aura/nanoaura (owner, src)
+
/obj/item/organ/internal/augment/active/nanounit/onRemove()
QDEL_NULL(aura)
..()
+
/obj/item/organ/internal/augment/active/nanounit/proc/catastrophic_failure()
playsound(owner,'sound/mecha/internaldmgalarm.ogg',25,1)
owner.visible_message(SPAN_WARNING("The nanites attempt to harden. But they seem... brittle."))
for(var/obj/item/organ/external/E in owner.organs)
- if(prob(25))
- E.status |= ORGAN_BRITTLE //Some nanites are not responding and you're out of luck
- to_chat(owner,SPAN_DANGER("Your [E.name] feels cold and rigid"))
+ if (prob(25))
+ E.status |= ORGAN_BRITTLE
+ to_chat(owner, SPAN_DANGER("Your [E.name] feels cold and rigid"))
QDEL_NULL(aura)
+
/obj/item/organ/internal/augment/active/nanounit/activate()
if(!aura || !can_activate())
return
if(aura.active)
- aura.active = 0
- to_chat(owner,SPAN_NOTICE("Nanites entering sleep mode."))
+ aura.active = FALSE
+ to_chat(owner, SPAN_NOTICE("Nanites entering sleep mode."))
else
- aura.active = 1
- to_chat(owner,SPAN_NOTICE("Activation sequence in progress."))
- playsound(owner,'sound/weapons/flash.ogg',35,1)
+ aura.active = TRUE
+ to_chat(owner, SPAN_NOTICE("Activation sequence in progress."))
+ playsound(owner, 'sound/weapons/flash.ogg', 35, 1)
/obj/item/organ/internal/augment/active/nanounit/Destroy()
. = ..()
QDEL_NULL(aura)
-/obj/aura/nanoaura/Initialize(var/maploading, var/obj/item/organ/internal/augment/active/nanounit/holder)
+
+/obj/aura/nanoaura
+ name = "Nanoaura"
+ var/obj/item/organ/internal/augment/active/nanounit/unit
+ var/active
+
+
+/obj/aura/nanoaura/Initialize(maploading, obj/item/organ/internal/augment/active/nanounit/holder)
. = ..()
unit = holder
- playsound(loc,'sound/weapons/flash.ogg',35,1)
- to_chat(loc,SPAN_NOTICE("Your skin tingles as the nanites spread over your body."))
+ playsound(loc, 'sound/weapons/flash.ogg',35,1)
+ to_chat(loc, SPAN_NOTICE("Your skin tingles as the nanites spread over your body."))
+
-/obj/aura/nanoaura/bullet_act(var/obj/item/projectile/P, var/def_zone)
- if(!active)
+/obj/aura/nanoaura/bullet_act(obj/item/projectile/P, def_zone)
+ if (!active)
return
- if(unit.charges > 0)
+ if (unit.charges > 0)
user.visible_message(SPAN_WARNING("The nanomachines harden as a response to physical trauma!"))
- playsound(user,'sound/effects/basscannon.ogg',35,1)
+ playsound(user, 'sound/effects/basscannon.ogg',35,1)
unit.charges -= 1
- if(prob(1))
- var/memesound = pick(unit.memesounds)
- playsound(user, memesound, 35, 1)
- if(unit.charges <= 0)
+ if (unit.charges <= 0)
to_chat(user, SPAN_DANGER("Warning: Critical damage treshold passed. Shut down unit to avoid further damage"))
- return AURA_FALSE|AURA_CANCEL
- else unit.catastrophic_failure()
+ return AURA_FALSE | AURA_CANCEL
+ unit.catastrophic_failure()
/obj/aura/nanoaura/Destroy()
diff --git a/code/modules/augment/simple.dm b/code/modules/augment/simple.dm
deleted file mode 100644
index af9577bacce..00000000000
--- a/code/modules/augment/simple.dm
+++ /dev/null
@@ -1,73 +0,0 @@
-//Simple toggleabse module. Just put holding in hands or get it back
-/obj/item/organ/internal/augment/active/simple
- var/obj/item/holding = null
- var/holding_type = null
-
-/obj/item/organ/internal/augment/active/simple/Initialize()
- . = ..()
- if(holding_type)
- holding = new holding_type(src)
- holding.canremove = 0
-
-/obj/item/organ/internal/augment/active/simple/Destroy()
- if(holding)
- GLOB.item_unequipped_event.unregister(holding, src)
- if(holding.loc == src)
- QDEL_NULL(holding)
-
-
-/obj/item/organ/internal/augment/active/simple/proc/holding_dropped()
-
- //Stop caring
- GLOB.item_unequipped_event.unregister(holding, src)
-
- if(holding.loc != src) //something went wrong and is no longer attached/ it broke
- holding.canremove = 1
- holding = null //We no longer hold this, you will have to get a replacement module or fix it somehow
-
-/obj/item/organ/internal/augment/active/simple/proc/deploy()
-
- var/slot = null
- if(limb.organ_tag in list(BP_L_ARM, BP_L_HAND))
- slot = slot_l_hand
- else if(limb.organ_tag in list(BP_R_ARM, BP_R_HAND))
- slot = slot_r_hand
- if(owner.equip_to_slot_if_possible(holding, slot))
- GLOB.item_unequipped_event.register(holding, src, /obj/item/organ/internal/augment/active/simple/proc/holding_dropped )
- owner.visible_message(
- SPAN_WARNING("[owner] extends \his [holding.name] from [limb]."),
- SPAN_NOTICE("You extend your [holding.name] from [limb].")
- )
-
-/obj/item/organ/internal/augment/active/simple/proc/retract()
- if(holding.loc == src)
- return
-
- if(ismob(holding.loc) && holding.loc == owner)
- var/mob/M = holding.loc
- if(!M.drop_from_inventory(holding, src))
- to_chat(owner, "\the [holding.name] fails to retract.")
- return
- M.visible_message(
- SPAN_WARNING("[M] retracts \his [holding.name] into [limb]."),
- SPAN_NOTICE("You retract your [holding.name] into [limb].")
- )
-
-
-
-/obj/item/organ/internal/augment/active/simple/activate()
- if(!can_activate())
- return
-
- if(holding.loc == src) //item not in hands
- deploy()
- else //retract item
- retract()
-
-/obj/item/organ/internal/augment/active/simple/can_activate()
- if(..())
- if(!holding)
- to_chat(owner, SPAN_WARNING("The device is damaged and fails to deploy"))
- return FALSE
- return TRUE
- return FALSE
\ No newline at end of file
diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm
index c74ef47f8fc..1454fe34473 100644
--- a/code/modules/client/preference_setup/loadout/loadout.dm
+++ b/code/modules/client/preference_setup/loadout/loadout.dm
@@ -404,9 +404,9 @@ var/list/gear_datums = list()
var/obj/item/item = spawn_item(H, metadata)
item.add_fingerprint(H)
- if(implanted)
- implant_into_mob(H, item)
- return //avoids weird stuff.
+// if(implanted)
+// implant_into_mob(H, item)
+// return //avoids weird stuff.
var/atom/placed_in = H.equip_to_storage(item)
if(placed_in)
to_chat(H, "Placing \the [item] in your [placed_in.name]!")
@@ -417,7 +417,7 @@ var/list/gear_datums = list()
else
to_chat(H, "Dropping \the [item] on the ground!")
-/datum/gear/proc/implant_into_mob(var/mob/living/carbon/human/H, obj/item/I)
+/*/datum/gear/proc/implant_into_mob(var/mob/living/carbon/human/H, obj/item/I)
var/obj/item/organ/external/organ_to_implant_into = H.get_organ(BP_CHEST)
if(istype(I, /obj/item/organ/internal/augment)) //We are an augment, figure out the parent organ we go into.
@@ -438,3 +438,4 @@ var/list/gear_datums = list()
IM.forceMove(organ_to_implant_into)
IM.implanted(H) //just in case
to_chat(H, SPAN_NOTICE("Implanting you with [IM] in your [organ_to_implant_into.name]!"))
+*/
\ No newline at end of file
diff --git a/code/modules/organs/external/_external_damage.dm b/code/modules/organs/external/_external_damage.dm
index 354ce034f6c..fa133333b96 100644
--- a/code/modules/organs/external/_external_damage.dm
+++ b/code/modules/organs/external/_external_damage.dm
@@ -323,7 +323,7 @@ obj/item/organ/external/take_general_damage(var/amount, var/silent = FALSE)
return FALSE
/obj/item/organ/external/proc/get_brute_mod(var/damage_flags)
- var/obj/item/organ/internal/augment/armor/A = owner && owner.internal_organs_by_name[BP_AUGMENT_CHEST_ARMOUR]
+ var/obj/item/organ/internal/augment/armor/A = owner && owner.internal_organs_by_name["[BP_CHEST]_aug_armor"]
var/B = 1
if(A && istype(A))
B = A.brute_mult
@@ -337,7 +337,7 @@ obj/item/organ/external/take_general_damage(var/amount, var/silent = FALSE)
return B + (0.2 * burn_dam/max_damage) //burns make you take more brute damage
/obj/item/organ/external/proc/get_burn_mod(var/damage_flags)
- var/obj/item/organ/internal/augment/armor/A = owner && owner.internal_organs_by_name[BP_AUGMENT_CHEST_ARMOUR]
+ var/obj/item/organ/internal/augment/armor/A = owner && owner.internal_organs_by_name["[BP_CHEST]_aug_armor"]
var/B = 1
if(A && istype(A))
B = A.burn_mult
diff --git a/code/modules/organs/external/diagnostics.dm b/code/modules/organs/external/diagnostics.dm
index 66ee87fabaf..8be8a8b198c 100644
--- a/code/modules/organs/external/diagnostics.dm
+++ b/code/modules/organs/external/diagnostics.dm
@@ -105,8 +105,8 @@
unknown_body++
if(unknown_body)
. += "Unknown body present"
- for(var/obj/item/organ/internal/augment/aug in internal_organs)
- if(istype(aug) && aug.known)
+ for (var/obj/item/organ/internal/augment/aug in internal_organs)
+ if (aug.augment_flags & AUGMENT_SCANNABLE)
. += "[capitalize(aug.name)] implanted"
/obj/item/organ/external/proc/inspect(mob/user)
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 5fa5de001f3..86282eb0be8 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -384,3 +384,10 @@ var/list/organ_cache = list()
/obj/item/organ/proc/get_mechanical_assisted_descriptor()
return "mechanically-assisted [name]"
+
+/**
+* Pre-surgery modification of the organ if it has status|ORGAN_CONFIGURE
+* Halts surgery if the return value is truthy
+*/
+/obj/item/organ/proc/surgery_configure(mob/living/user, mob/living/carbon/human/target, obj/item/organ/parent, obj/item/tool, decl/surgery_step/action)
+ return
diff --git a/code/modules/research/designs/designs_mechfab.dm b/code/modules/research/designs/designs_mechfab.dm
index 1330c3c1def..c1ec11c9094 100644
--- a/code/modules/research/designs/designs_mechfab.dm
+++ b/code/modules/research/designs/designs_mechfab.dm
@@ -466,14 +466,14 @@
/datum/design/item/mechfab/augment/armblade
name = "Armblade"
- build_path = /obj/item/organ/internal/augment/active/simple/armblade
+ build_path = /obj/item/organ/internal/augment/active/item/armblade
materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 750)
req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 2, TECH_MATERIAL = 4, TECH_BIO = 3)
id = "augment_blade"
/datum/design/item/mechfab/augment/armblade/wolverine
name = "Cyberclaws"
- build_path = /obj/item/organ/internal/augment/active/simple/wolverine
+ build_path = /obj/item/material/armblade/claws
materials = list(DEFAULT_WALL_MATERIAL = 6000, "diamond" = 250)
req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 4, TECH_MATERIAL = 4, TECH_BIO = 3)
id = "augment_wolverine"
@@ -522,7 +522,7 @@
/datum/design/item/mechfab/augment/circuit
name = "Integrated circuit frame"
- build_path = /obj/item/organ/internal/augment/active/simple/circuit
+ build_path = /obj/item/organ/internal/augment/active/item/circuit
materials = list(DEFAULT_WALL_MATERIAL = 3000)
id = "augment_circuitry"
diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm
index 1204c1d7476..ce83f94e378 100644
--- a/code/modules/surgery/limb_reattach.dm
+++ b/code/modules/surgery/limb_reattach.dm
@@ -33,8 +33,17 @@
. = FALSE
var/obj/item/organ/external/E = tool
var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ]
+ var/obj/item/organ/external/T = target.organs_by_name[E.organ_tag]
+
+ if ((E.status & ORGAN_CONFIGURE) && E.surgery_configure(user, target, P, tool, src))
+ return
+
if(!P || P.is_stump())
to_chat(user, SPAN_WARNING("The [E.amputation_point] is missing!"))
+ else if(T && T.is_stump())
+ to_chat(user, SPAN_WARNING("You cannot attach \a [E] when there is a stump!"))
+ else if(T)
+ to_chat(user, SPAN_WARNING("There is already \a [E]!"))
else if(BP_IS_ROBOTIC(P) && !BP_IS_ROBOTIC(E))
to_chat(user, SPAN_WARNING("You cannot attach a flesh part to a robotic body."))
else if(BP_IS_CRYSTAL(P) && !BP_IS_CRYSTAL(E))
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 7f13694f99d..03ffcbb25ab 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -231,6 +231,10 @@
. = FALSE
var/obj/item/organ/internal/O = tool
var/obj/item/organ/external/affected = target.get_organ(target_zone)
+
+ if ((O.status & ORGAN_CONFIGURE) && O.surgery_configure(user, target, affected, tool, src))
+ return
+
if(istype(O) && istype(affected))
if(BP_IS_CRYSTAL(O) && !BP_IS_CRYSTAL(affected))
to_chat(user, SPAN_WARNING("You cannot install a crystalline organ into a non-crystalline bodypart."))
@@ -331,7 +335,7 @@
if(istype(organ_to_replace, /obj/item/organ/internal/augment))
var/obj/item/organ/internal/augment/A = organ_to_replace
- if(!(A.augment_flags & AUGMENTATION_ORGANIC))
+ if(!(A.augment_flags & AUGMENT_BIOLOGICAL))
to_chat(user, SPAN_WARNING("\The [A] cannot function within a non-robotic limb."))
return FALSE
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 163821768b8..fdf4821c59d 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -471,7 +471,7 @@ decl/surgery_step/robotics/get_skill_reqs(mob/living/user, mob/living/carbon/hum
var/obj/item/organ/organ_to_replace = show_radial_menu(user, target, attachable_organs)
if(istype(organ_to_replace, /obj/item/organ/internal/augment))
var/obj/item/organ/internal/augment/A = organ_to_replace
- if(!(A.augment_flags & AUGMENTATION_MECHANIC))
+ if(!(A.augment_flags & AUGMENT_MECHANICAL))
to_chat(user, SPAN_WARNING("\The [A] cannot function within a robotic limb!"))
return FALSE
return organ_to_replace
diff --git a/maps/torch/loadout/loadout_augments.dm b/maps/torch/loadout/loadout_augments.dm
index c52c7df9193..39f22a0ef44 100644
--- a/maps/torch/loadout/loadout_augments.dm
+++ b/maps/torch/loadout/loadout_augments.dm
@@ -1,5 +1,6 @@
//combat
//utility
+/*
/datum/gear/augmentation/implanted_surgical
display_name = "surgical polytool - left arm (ROBOTIC)"
path = /obj/item/organ/internal/augment/active/polytool/surgical/left
@@ -26,4 +27,6 @@
/datum/gear/augmentation/implanted_circuitkit/right
display_name = "circuit augment - right arm (ROBOTIC)"
- path = /obj/item/organ/internal/augment/active/simple/circuit/right
\ No newline at end of file
+ path = /obj/item/organ/internal/augment/active/simple/circuit/right
+
+*/
\ No newline at end of file
From 0fc176eb68d291e87de762ec099983b8ca54ff8a Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Thu, 31 Mar 2022 09:49:01 -0400
Subject: [PATCH 2/9] Updates test checks
---
test/check-paths.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/check-paths.sh b/test/check-paths.sh
index b259c17d1a7..cb43c5d0b23 100755
--- a/test/check-paths.sh
+++ b/test/check-paths.sh
@@ -31,7 +31,7 @@ exactly 10 "/obj text paths" '"/obj'
exactly 8 "/turf text paths" '"/turf'
exactly 0 "world<< uses" 'world<<|world[[:space:]]<<'
exactly 43 "world.log<< uses" 'world.log<<|world.log[[:space:]]<<'
-exactly 480 "<< uses" '(?
Date: Thu, 31 Mar 2022 10:28:54 -0400
Subject: [PATCH 3/9] Fixes strange use of parent referral
---
code/_onclick/hud/ability_screen_objects.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm
index b0a4ba461af..8fcad84a751 100644
--- a/code/_onclick/hud/ability_screen_objects.dm
+++ b/code/_onclick/hud/ability_screen_objects.dm
@@ -163,8 +163,8 @@
ability_master.toggle_open(1)
/mob/Initialize()
- ability_master = new /obj/screen/movable/ability_master(null,src)
. = ..()
+ ability_master = new /obj/screen/movable/ability_master(null,src)
///////////ACTUAL ABILITIES////////////
//This is what you click to do things//
From 4565bf78220953f0c66f54a4ff47c29f2ca3fb4d Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Sun, 3 Apr 2022 04:11:37 -0400
Subject: [PATCH 4/9] Armblade paths
---
code/modules/augment/active/armblades.dm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm
index a17791c6318..0de4a797589 100644
--- a/code/modules/augment/active/armblades.dm
+++ b/code/modules/augment/active/armblades.dm
@@ -1,4 +1,4 @@
-/obj/item/material/armblade
+/obj/item/weapon/material/armblade
icon_state = "armblade"
item_state = null
name = "armblade"
@@ -21,7 +21,7 @@
augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE
-/obj/item/material/armblade/claws
+/obj/item/weapon/material/armblade/claws
icon_state = "wolverine"
name = "combat claws"
desc = "These do not grow back."
@@ -52,7 +52,7 @@
augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL
-/obj/item/material/armblade/wrist
+/obj/item/weapon/material/armblade/wrist
name = "wrist blade"
desc = "A thin and very sharp folding blade specially made for combat, made from a specialized alloy that prevents all that nasty blood and viscera from sticking to it. Its light weight allows for rapid slashing attacks."
icon_state = "wristblade"
From ff85e292d9a8998bb000ad42b5921e42155be932 Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Sun, 3 Apr 2022 04:30:16 -0400
Subject: [PATCH 5/9] Fixes more errors
---
code/modules/augment/active/armblades.dm | 8 ++++----
code/modules/research/designs/designs_mechfab.dm | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm
index 0de4a797589..85693c37a2a 100644
--- a/code/modules/augment/active/armblades.dm
+++ b/code/modules/augment/active/armblades.dm
@@ -17,7 +17,7 @@
action_button_name = "Deploy blade"
icon_state = "armblade"
augment_slots = AUGMENT_ARM
- item = /obj/item/material/armblade
+ item = /obj/item/weapon/material/armblade
augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE
@@ -34,7 +34,7 @@
action_button_name = "Deploy claws"
icon_state = "wolverine"
augment_slots = AUGMENT_HAND
- item = /obj/item/material/armblade/claws
+ item = /obj/item/weapon/material/armblade/claws
augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE
@@ -45,7 +45,7 @@
action_button_name = "Deploy blade"
icon_state = "armblade"
augment_slots = AUGMENT_ARM
- item = /obj/item/material/armblade/wrist
+ item = /obj/item/weapon/material/armblade/wrist
origin_tech = list(TECH_COMBAT = 3, TECH_ESOTERIC = 4)
deploy_sound = 'sound/effects/holster/sheathout.ogg'
retract_sound = 'sound/effects/holster/sheathin.ogg'
@@ -63,5 +63,5 @@
w_class = ITEM_SIZE_SMALL
-/obj/item/material/armblade/wrist/add_blood(mob/living/carbon/human/M)
+/obj/item/weapon/material/armblade/wrist/add_blood(mob/living/carbon/human/M)
return FALSE
diff --git a/code/modules/research/designs/designs_mechfab.dm b/code/modules/research/designs/designs_mechfab.dm
index c1ec11c9094..2bfacc7d667 100644
--- a/code/modules/research/designs/designs_mechfab.dm
+++ b/code/modules/research/designs/designs_mechfab.dm
@@ -473,7 +473,7 @@
/datum/design/item/mechfab/augment/armblade/wolverine
name = "Cyberclaws"
- build_path = /obj/item/material/armblade/claws
+ build_path = /obj/item/organ/internal/augment/active/item/wolverine
materials = list(DEFAULT_WALL_MATERIAL = 6000, "diamond" = 250)
req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 4, TECH_MATERIAL = 4, TECH_BIO = 3)
id = "augment_wolverine"
From c1a519f7574901707773fd5ca58389b6618bcf85 Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Sun, 3 Apr 2022 05:16:33 -0400
Subject: [PATCH 6/9] Makes armblades work. Holy shit I hate null vars.
---
code/modules/augment/item.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/modules/augment/item.dm b/code/modules/augment/item.dm
index 34009e345de..23ac0ff1d03 100644
--- a/code/modules/augment/item.dm
+++ b/code/modules/augment/item.dm
@@ -54,8 +54,6 @@
GLOB.item_unequipped_event.unregister(item, src)
if (item.loc != src) // It fell off!
item.canremove = TRUE
- item = null
-
/obj/item/organ/internal/augment/active/item/proc/deploy(as_owner = TRUE)
if (!slot)
From d6e9137912256f1ea65a4818e39b67fc783b93f2 Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Sun, 3 Apr 2022 06:56:03 -0400
Subject: [PATCH 7/9] Adds some comments so that people know how these work.
---
code/modules/augment/active/armblades.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm
index 85693c37a2a..92d70fb396a 100644
--- a/code/modules/augment/active/armblades.dm
+++ b/code/modules/augment/active/armblades.dm
@@ -1,10 +1,10 @@
-/obj/item/weapon/material/armblade
+/obj/item/weapon/material/armblade //Tested in game, force = 30 with steel which is what it's usually made of. Variations can exist.
icon_state = "armblade"
item_state = null
name = "armblade"
icon = 'icons/obj/augment.dmi'
desc = "A handy utility blade for the discerning augmentee. Warranty void if used for cutting."
- base_parry_chance = 30
+ base_parry_chance = 30 //Difference between armblades is how well it parries and the blade size, which controls what it can dismember
unacidable = TRUE
sharp = TRUE
edge = TRUE
From 8e9a12d5eb3c73ee69c19cd03818096524f9e5ae Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Mon, 4 Apr 2022 11:43:24 -0400
Subject: [PATCH 8/9] Adds powerfists, pop-out gun, extras
---
baystation12.dme | 9 +
.../augment/active/adaptive_binoculars.dm | 21 ++
.../augment/active/corrective_lenses.dm | 21 ++
.../modules/augment/active/glare_dampeners.dm | 9 +
code/modules/augment/active/iatric_monitor.dm | 26 +++
.../augment/active/leukocyte_breeder.dm | 69 ++++++
.../modules/augment/active/nerve_dampeners.dm | 45 ++++
code/modules/augment/active/popout_guns.dm | 30 +++
code/modules/augment/active/powerfists.dm | 208 ++++++++++++++++++
code/modules/augment/implanter.dm | 173 +++++++++++++++
code/modules/clothing/glasses/glasses.dm | 26 +++
11 files changed, 637 insertions(+)
create mode 100644 code/modules/augment/active/adaptive_binoculars.dm
create mode 100644 code/modules/augment/active/corrective_lenses.dm
create mode 100644 code/modules/augment/active/glare_dampeners.dm
create mode 100644 code/modules/augment/active/iatric_monitor.dm
create mode 100644 code/modules/augment/active/leukocyte_breeder.dm
create mode 100644 code/modules/augment/active/nerve_dampeners.dm
create mode 100644 code/modules/augment/active/popout_guns.dm
create mode 100644 code/modules/augment/active/powerfists.dm
create mode 100644 code/modules/augment/implanter.dm
diff --git a/baystation12.dme b/baystation12.dme
index 996133f9bc4..f9b001040fa 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1453,11 +1453,20 @@
#include "code\modules\atmospherics\components\unary\vent_scrubber.dm"
#include "code\modules\augment\active.dm"
#include "code\modules\augment\augment.dm"
+#include "code\modules\augment\implanter.dm"
#include "code\modules\augment\item.dm"
+#include "code\modules\augment\active\adaptive_binoculars.dm"
#include "code\modules\augment\active\armblades.dm"
#include "code\modules\augment\active\circuit.dm"
+#include "code\modules\augment\active\corrective_lenses.dm"
+#include "code\modules\augment\active\glare_dampeners.dm"
#include "code\modules\augment\active\hudimplants.dm"
+#include "code\modules\augment\active\iatric_monitor.dm"
+#include "code\modules\augment\active\leukocyte_breeder.dm"
+#include "code\modules\augment\active\nerve_dampeners.dm"
#include "code\modules\augment\active\polytool.dm"
+#include "code\modules\augment\active\popout_guns.dm"
+#include "code\modules\augment\active\powerfists.dm"
#include "code\modules\augment\active\tool\engineering.dm"
#include "code\modules\augment\active\tool\surgical.dm"
#include "code\modules\augment\passive\armor.dm"
diff --git a/code/modules/augment/active/adaptive_binoculars.dm b/code/modules/augment/active/adaptive_binoculars.dm
new file mode 100644
index 00000000000..fc93f00bc70
--- /dev/null
+++ b/code/modules/augment/active/adaptive_binoculars.dm
@@ -0,0 +1,21 @@
+/obj/item/organ/internal/augment/active/item/adaptive_binoculars
+ name = "adaptive binoculars"
+ augment_slots = AUGMENT_HEAD
+ icon_state = "adaptive_binoculars"
+ desc = "Digital glass 'screens' can be deployed over the eyes. At the user's control, their image can be greatly enhanced, providing a view of distant areas."
+ action_button_name = "Deploy lenses"
+ origin_tech = list(TECH_DATA = 3, TECH_BIO = 2)
+ item = /obj/item/clothing/glasses/augment_binoculars
+
+
+/obj/item/organ/internal/augment/active/item/adaptive_binoculars/hidden
+ augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL
+
+
+/obj/item/organ/internal/augment/active/item/adaptive_binoculars/emp_act(severity)
+ . = ..()
+ if (item?.zoom)
+ to_chat(owner, SPAN_WARNING("Your eyes fill with static as \the [item.name] malfunction\s!"))
+ owner.eye_blind += 10
+ owner.eye_blurry += 20
+ item.unzoom()
diff --git a/code/modules/augment/active/corrective_lenses.dm b/code/modules/augment/active/corrective_lenses.dm
new file mode 100644
index 00000000000..674e284a54d
--- /dev/null
+++ b/code/modules/augment/active/corrective_lenses.dm
@@ -0,0 +1,21 @@
+/obj/item/organ/internal/augment/active/item/corrective_lenses
+ name = "corrective lenses"
+ augment_slots = AUGMENT_HEAD
+ icon_state = "corrective_lenses"
+ desc = "A pair of retractable, ultrathin corrective lenses are installed into the eye sockets. They can be deployed or retracted at will and serve as prescription glasses."
+ action_button_name = "Deploy lenses"
+ augment_flags = AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE | AUGMENT_INSPECTABLE
+ origin_tech = list(TECH_DATA = 2, TECH_BIO = 2)
+ item = /obj/item/clothing/glasses/augment
+
+
+/obj/item/organ/internal/augment/active/item/corrective_lenses/onRoundstart()
+ deploy()
+
+
+/obj/item/clothing/glasses/augment
+ name = "corrective lenses"
+ desc = "The most expensive prescription on this side of Sol."
+ body_parts_covered = null
+ prescription = 7
+ unacidable = TRUE
diff --git a/code/modules/augment/active/glare_dampeners.dm b/code/modules/augment/active/glare_dampeners.dm
new file mode 100644
index 00000000000..b05646e1350
--- /dev/null
+++ b/code/modules/augment/active/glare_dampeners.dm
@@ -0,0 +1,9 @@
+/obj/item/organ/internal/augment/active/item/glare_dampeners
+ name = "glare dampeners"
+ augment_slots = AUGMENT_HEAD
+ icon_state = "glare_dampeners"
+ desc = "Thick, tinted lenses installed in your head can deploy over your eyes, reducing visibility but providing protection from welding glare and bright lights."
+ action_button_name = "Deploy dampeners"
+ augment_flags = AUGMENT_BIOLOGICAL
+ origin_tech = list(TECH_DATA = 2, TECH_BIO = 2)
+ item = /obj/item/clothing/glasses/glare_dampeners
diff --git a/code/modules/augment/active/iatric_monitor.dm b/code/modules/augment/active/iatric_monitor.dm
new file mode 100644
index 00000000000..63b1a091112
--- /dev/null
+++ b/code/modules/augment/active/iatric_monitor.dm
@@ -0,0 +1,26 @@
+/obj/item/organ/internal/augment/active/iatric_monitor
+ name = "iatric monitor"
+ augment_slots = AUGMENT_HEAD
+ icon_state = "iatric_monitor"
+ desc = "A small computer system constantly tracks your physiological state and vital signs. A muscle gesture can be used to receive a simple diagnostic report, not unlike that from a handheld scanner."
+ augment_flags = AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE
+ origin_tech = list(TECH_DATA = 3, TECH_BIO = 2)
+
+
+/obj/item/organ/internal/augment/active/iatric_monitor/emp_act(severity)
+ . = ..()
+ if (severity)
+ var/scan_results = medical_scan_results(owner, TRUE, SKILL_NONE)
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ to_chat(owner, "
[scan_results]
")
+ to_chat(owner, SPAN_WARNING("Your [name] cheerily outputs a bogus report as it malfunctions."))
+
+
+/obj/item/organ/internal/augment/active/iatric_monitor/activate()
+ var/scan_results = medical_scan_results(owner, TRUE, SKILL_PROF)
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ to_chat(owner, "
[scan_results]
")
+
+
+/obj/item/organ/internal/augment/active/iatric_monitor/hidden
+ augment_flags = AUGMENT_BIOLOGICAL
diff --git a/code/modules/augment/active/leukocyte_breeder.dm b/code/modules/augment/active/leukocyte_breeder.dm
new file mode 100644
index 00000000000..a01f9ae7326
--- /dev/null
+++ b/code/modules/augment/active/leukocyte_breeder.dm
@@ -0,0 +1,69 @@
+/obj/item/organ/internal/augment/active/leukocyte_breeder
+ name = "leukocyte breeder"
+ augment_slots = AUGMENT_CHEST
+ icon_state = "leukosuite"
+ desc = "These stimulators augment the immune system and promote the growth of hunter-killer cells in the presence of a foreign invader, effectively boosting the body's immunity to parasites and disease."
+ action_button_name = "Toggle leukocyte breeder"
+ augment_flags = AUGMENT_BIOLOGICAL
+ origin_tech = list(TECH_DATA = 2, TECH_BIO = 4)
+ var/active = FALSE
+
+ /// How many processing ticks the augment has been enabled for
+ var/ticks_active = 0
+
+ /// After this many ticks, the owner has "broken in" the augment, and will benefit more but suffer drawbacks if it's disabled
+ var/ticks_to_acclimate = 120
+
+
+/obj/item/organ/internal/augment/active/leukocyte_breeder/emp_act(severity)
+ . = ..()
+ if (owner && active)
+ if (prob(100 - (20 * severity))) // 40% chance for 3, 60% chance for 2, and 80% chance for 1 severity, respectively
+ to_chat(owner, SPAN_WARNING("You feel a wave of nausea as your [name] deactivates."))
+ active = FALSE
+
+
+/obj/item/organ/internal/augment/active/leukocyte_breeder/onRoundstart()
+ active = TRUE // We can safely assume that someone starting off with the breeder will have it active
+ ticks_active = ticks_to_acclimate
+ to_chat(owner, SPAN_NOTICE("Your [name] has started the shift active, granting you its full benefits without needing to break it in."))
+
+
+/obj/item/organ/internal/augment/active/leukocyte_breeder/onInstall()
+ if (prob(10))
+ ticks_active = ticks_to_acclimate // Some folks are just lucky and don't get any side effects
+
+
+/obj/item/organ/internal/augment/active/leukocyte_breeder/activate()
+ if (!can_activate())
+ return
+ if (active && ticks_active >= ticks_to_acclimate)
+ // Give an alert if trying to deactivate while acclimated, so roundstart takers don't accidentally turn it off by learning the buttons
+ if (alert(owner, "Deactivate \the [src]?", name, "Yes", "No") != "Yes" || !can_activate())
+ return
+ active = !active
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ if (active)
+ to_chat(owner, SPAN_NOTICE("Leukocyte breeder engaged and improving immune response."))
+ else
+ to_chat(owner, SPAN_WARNING("Leukocyte breeder disengaged. Short-term health may suffer."))
+ if (owner.immunity >= (owner.immunity_norm * 0.9)) // Reduce short-term immunity, but only if it's at around normal levels
+ owner.immunity -= 10
+ ticks_active = 0
+
+
+/obj/item/organ/internal/augment/active/leukocyte_breeder/Process()
+ if (!owner)
+ return
+ if (active)
+ ticks_active++
+ if (owner.immunity < owner.immunity_norm * 1.1)
+ owner.immunity += 0.05
+ ticks_active++
+ if (ticks_active < ticks_to_acclimate)
+ if (ticks_active < ticks_to_acclimate)
+ if (prob(5))
+ owner.emote(pick("cough", "sneeze"))
+ if (prob(3))
+ to_chat(owner, SPAN_WARNING(pick("You feel uncomfortably hot.", "Your head aches.", "You feel lightheaded.")))
+ owner.dizziness += rand(3, 5)
diff --git a/code/modules/augment/active/nerve_dampeners.dm b/code/modules/augment/active/nerve_dampeners.dm
new file mode 100644
index 00000000000..9ee2fb1613a
--- /dev/null
+++ b/code/modules/augment/active/nerve_dampeners.dm
@@ -0,0 +1,45 @@
+/obj/item/organ/internal/augment/active/nerve_dampeners
+ name = "nerve dampeners"
+ augment_slots = AUGMENT_CHEST
+ icon_state = "muscule"
+ desc = "Each activation of this augment provides a strong painkilling effect for around thirty seconds, but will be followed by a powerful comedown. Excessive short-term use may cause brain damage."
+ augment_flags = AUGMENT_BIOLOGICAL
+ origin_tech = list(TECH_DATA = 4, TECH_BIO = 4)
+ var/ticks_remaining = 0
+
+
+/obj/item/organ/internal/augment/active/nerve_dampeners/can_activate()
+ if (ticks_remaining)
+ to_chat(owner, SPAN_WARNING("Your [name] is already active."))
+ return
+ . = ..()
+
+
+/obj/item/organ/internal/augment/active/nerve_dampeners/activate()
+ if (!can_activate())
+ return
+ to_chat(owner, SPAN_NOTICE("You activate your [name], and feel a wave of numbness wash over you!"))
+ ticks_remaining = 15
+ if (owner.drowsyness)
+ to_chat(owner, SPAN_DANGER("Your body slackens as you lose sensation."))
+ if (prob(owner.getBrainLoss()))
+ to_chat(owner, SPAN_DANGER("You slump to the ground and black out."))
+ owner.Paralyse(10)
+ owner.adjustBrainLoss(owner.drowsyness)
+
+
+/obj/item/organ/internal/augment/active/nerve_dampeners/Process()
+ if (!owner)
+ return
+ if (ticks_remaining)
+ ticks_remaining--
+ owner.add_chemical_effect(CE_PAINKILLER, 160) // About twice as strong as tramadol at full strength
+ if (!ticks_remaining) // ...but comes at a price. Brief short term benefit for a long-term comedown
+ to_chat(owner, SPAN_WARNING("You abruptly feel intensely exhausted as sensation returns."))
+ owner.drowsyness = max(owner.drowsyness, 15)
+ owner.confused = max(owner.confused, 15)
+ owner.slurring = max(owner.slurring, 30)
+ owner.chem_effects[CE_PAINKILLER] = 0
+ owner.stamina = 0
+ if(MOVING_QUICKLY(owner))
+ owner.set_moving_slowly()
diff --git a/code/modules/augment/active/popout_guns.dm b/code/modules/augment/active/popout_guns.dm
new file mode 100644
index 00000000000..758a1d093e6
--- /dev/null
+++ b/code/modules/augment/active/popout_guns.dm
@@ -0,0 +1,30 @@
+/obj/item/organ/internal/augment/active/item/popout_shotgun
+ name = "pop-out shotgun"
+ desc = "A galvanized steel mechanism that replaces most of the flesh below the elbow. Using the arm's natural range of motion as a hinge, it can be flicked open to reveal a 12-gauge shotgun with room for a single shell."
+ action_button_name = "Deploy shotgun"
+ icon_state = "popout_shotgun"
+ augment_slots = AUGMENT_ARM
+ item = /obj/item/weapon/gun/projectile/shotgun/popout
+ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_ESOTERIC = 4)
+ deploy_sound = 'sound/weapons/guns/interaction/rifle_boltback.ogg'
+ retract_sound = 'sound/weapons/guns/interaction/rifle_boltforward.ogg'
+ augment_flags = AUGMENT_MECHANICAL | AUGMENT_BIOLOGICAL | AUGMENT_SCANNABLE | AUGMENT_INSPECTABLE
+
+
+/obj/item/weapon/gun/projectile/shotgun/popout
+ name = "pop-out shotgun"
+ desc = "A specialized 12-gauge shotgun concealed in the forearm. If you plan to shoot, you better not miss."
+ icon = 'icons/obj/augment.dmi'
+ icon_state = "popout_shotgun"
+ item_state = "coilgun"
+ max_shells = 1
+ w_class = ITEM_SIZE_HUGE
+ force = 5
+ obj_flags = OBJ_FLAG_CONDUCTIBLE
+ caliber = CALIBER_SHOTGUN
+ load_method = SINGLE_CASING|SINGLE_LOAD
+ ammo_type = /obj/item/ammo_casing/shotgun/pellet
+ handle_casings = EJECT_CASINGS
+ load_sound = 'sound/weapons/guns/interaction/shotgun_instert.ogg'
+ has_safety = FALSE // No brakes on this train baby
+ unacidable = TRUE
diff --git a/code/modules/augment/active/powerfists.dm b/code/modules/augment/active/powerfists.dm
new file mode 100644
index 00000000000..493f05c55ef
--- /dev/null
+++ b/code/modules/augment/active/powerfists.dm
@@ -0,0 +1,208 @@
+/obj/item/weapon/powerfist
+ icon_state = "powerfist"
+ item_state = "powerfist"
+ name = "pneumatic powerfist"
+ icon = 'icons/obj/augment.dmi'
+ desc = "A strong, pneumatic powerfist. Packs quite the punch with other utility uses."
+ base_parry_chance = 12
+ force = 5
+ attack_cooldown = 1.5 * DEFAULT_WEAPON_COOLDOWN
+ hitsound = 'sound/effects/bamf.ogg'
+ attack_verb = list("smashed", "bludgeoned", "hammered", "battered")
+
+ var/obj/item/weapon/tank/tank
+ var/pressure_setting
+ var/list/possible_pressure_amounts = list(10, 20, 30, 50)
+
+
+/obj/item/weapon/powerfist/Initialize()
+ . = ..()
+ if (ispath(tank))
+ tank = new tank (src)
+ if (!pressure_setting)
+ pressure_setting = possible_pressure_amounts[1]
+ update_force()
+
+
+/obj/item/organ/internal/augment/active/item/powerfist
+ name = "pneumatic power gauntlet"
+ desc = "An armoured powered gauntlet for the arm. Your very own pneumatic doom machine."
+ action_button_name = "Deploy powerfist"
+ icon_state = "powerfist"
+ deploy_sound = 'sound/machines/suitstorage_cycledoor.ogg'
+ retract_sound = 'sound/machines/suitstorage_cycledoor.ogg'
+ augment_slots = AUGMENT_ARM
+ item = /obj/item/weapon/powerfist
+ augment_flags = AUGMENT_MECHANICAL | AUGMENT_SCANNABLE
+
+
+/obj/item/weapon/powerfist/attackby(obj/item/item, mob/user)
+ if (!istype(item, /obj/item/weapon/tank/emergency) || istype(item, /obj/item/weapon/tank/emergency/oxygen/double)) //Make sure the tank isn't too big or it'll gib people
+ to_chat(user, SPAN_WARNING("\The [src] only slots small tanks!"))
+ return
+ if (tank)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [tank] installed."))
+ return
+ user.visible_message(
+ SPAN_ITALIC("\The [user] starts connecting \a [item] to \his [src]."),
+ SPAN_ITALIC("You start connecting \the [item] to \the [src]."),
+ range = 5
+ )
+ if (!do_after(user, 3 SECONDS, item, progress = 0))
+ return
+ if (!user.unEquip(item, src))
+ return
+ user.visible_message(
+ SPAN_ITALIC("\The [user] finishes connecting \a [item] to \his [src]."),
+ SPAN_NOTICE("You finish connecting \the [item] to \the [src]."),
+ range = 5
+ )
+ playsound(user, 'sound/effects/refill.ogg', 50, 1, -6)
+ tank = item
+ update_force()
+ update_icon()
+
+
+/obj/item/weapon/powerfist/proc/update_force()
+ var/pressure = tank?.air_contents?.return_pressure()
+ if (pressure > 210)
+ force = (pressure * pressure_setting * 0.01) * (tank.volume / 425)
+ else
+ force = 5
+
+
+/obj/item/weapon/powerfist/verb/set_pressure_verb()
+ set name = "Set Powerfist Pressure"
+ set desc = "Set the powerfist's tank output pressure."
+ set category = "Object"
+ set src in range(0)
+ set_pressure()
+
+
+/obj/item/weapon/powerfist/proc/set_pressure()
+ var/N = input("Percentage of tank used per hit:", "[src]") as null | anything in possible_pressure_amounts
+ if (isnull(N))
+ return
+ pressure_setting = N
+ to_chat(usr, SPAN_NOTICE("You dial \the [src]'s pressure valve to [pressure_setting]%."))
+ update_force()
+
+
+/obj/item/weapon/powerfist/attack_self(mob/living/carbon/human/user)
+ set_pressure()
+
+
+/obj/item/weapon/powerfist/attack_hand(mob/living/user)
+ if (!tank)
+ to_chat(user, SPAN_WARNING("There's no tank in \the [src]."))
+ return
+ user.visible_message(
+ SPAN_ITALIC("\The [user] starts disconnecting \a [tank] from \his [src]."),
+ SPAN_ITALIC("You start disconnecting \the [tank] from \the [src]."),
+ range = 5
+ )
+ if (!do_after(user, 3 SECONDS, src, progress = 0))
+ return
+ user.visible_message(
+ SPAN_ITALIC("\The [user] finishes disconnecting \a [tank] from \his [src]."),
+ SPAN_NOTICE("You finish disconnecting \the [tank] from \the [src]."),
+ range = 5
+ )
+ user.put_in_hands(tank)
+ playsound(loc, 'sound/effects/spray3.ogg', 50)
+ tank = null
+ update_icon()
+ update_force()
+
+
+/obj/item/weapon/powerfist/on_update_icon()
+ ..()
+ if (tank)
+ overlays += image(icon, "powerfist_tank")
+ else
+ overlays -= image(icon,"powerfist_tank")
+
+
+/obj/item/weapon/powerfist/examine(mob/living/user, distance)
+ . = ..()
+ if (distance > 2)
+ return
+ to_chat(user, "The valve is dialed to [pressure_setting]%.")
+ if (tank)
+ to_chat(user, "\A [tank] is fitted in \the [src]'s tank valve.")
+ to_chat(user, "The tank dial reads [tank.air_contents.return_pressure()] kPa.")
+ else
+ to_chat(user, "Nothing is attached to the tank valve!")
+
+
+/obj/item/weapon/powerfist/proc/gas_loss()
+ if (tank?.air_contents)
+ var/lost_gas = tank.air_contents.total_moles * pressure_setting * 0.01
+ tank.remove_air(lost_gas)
+
+
+/obj/item/weapon/powerfist/proc/no_pressure()
+ if (tank && tank.air_contents?.return_pressure() < 210)
+ playsound(usr, 'sound/machines/rigerror.ogg', 50)
+ to_chat(usr, SPAN_WARNING("\The pressure dial on \the [src] flashes a warning: it's out of gas!"))
+ update_force()
+
+
+/obj/item/weapon/powerfist/afterattack(atom/target, mob/living/user, inrange, params)
+ if (!inrange || user.a_intent == I_HELP)
+ return
+ if (tank && tank.air_contents.return_pressure() > 210 && pressure_setting > 20 && inrange)
+ playsound(user, 'sound/effects/bamf.ogg', pressure_setting*2, 1) //louder the more pressure is used
+ gas_loss()
+ no_pressure()
+ if (istype(target, /obj/machinery/door/airlock) && pressure_setting > 30) //tearing open airlocks
+ var/obj/machinery/door/airlock/A = target
+ if (!A.operating && !A.locked)
+ if (A.welded)
+ A.visible_message(SPAN_DANGER("\The [user] forces the fingers of \the [src] in through the welded metal, beginning to pry \the [A] open!"))
+ if (do_after(user, 13 SECONDS, A, progress = 0) && !A.locked)
+ A.welded = FALSE
+ A.update_icon()
+ playsound(A, 'sound/effects/meteorimpact.ogg', 100, 1)
+ playsound(A, 'sound/machines/airlock_creaking.ogg', 100, 1)
+ A.visible_message(SPAN_DANGER("\The [user] tears \the [A] open with \a [src]!"))
+ addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/open, TRUE), 0)
+ A.set_broken(TRUE)
+ return
+ else
+ A.visible_message(SPAN_DANGER("\The [user] pries the fingers of \a [src] in, beginning to force \the [A]!"))
+ if ((A.is_broken(NOPOWER) || do_after(user, 10 SECONDS, A, progress = 0)) && !(A.operating || A.welded || A.locked))
+ playsound(A, 'sound/machines/airlock_creaking.ogg', 100, 1)
+ if (A.density)
+ addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/open, TRUE), 0)
+ if(!A.is_broken(NOPOWER))
+ A.set_broken(TRUE)
+ A.visible_message(SPAN_DANGER("\The [user] forces \the [A] open with \a [src]!"))
+ else
+ addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/close, TRUE), 0)
+ if (!A.is_broken(NOPOWER))
+ A.set_broken(TRUE)
+ A.visible_message(SPAN_DANGER("\The [user] forces \the [A] closed with \a [src]!"))
+ if (A.locked)
+ to_chat(user, SPAN_WARNING("The airlock's bolts prevent it from being forced."))
+
+
+/obj/item/weapon/powerfist/apply_hit_effect(atom/target, mob/living/user)
+ if (tank)
+ gas_loss()
+ no_pressure()
+ if (istype(target, /mob/living))
+ if (pressure_setting == 50 && tank.air_contents.return_pressure() > 210)
+ var/mob/living/A = target
+ A.throw_at(get_edge_target_turf(user, user.dir), pressure_setting/10, pressure_setting/10) //penultimate/ultimate settings yeets people
+ user.visible_message(
+ SPAN_DANGER("\The [user] batters \the [A] with \a [src], sending them flying!"),
+ SPAN_WARNING("You batter \the [A] with \the [src], sending them flying!")
+ )
+ return ..()
+
+/obj/item/weapon/powerfist/prepared
+ tank = /obj/item/weapon/tank/emergency/oxygen/engi
+
+/obj/item/organ/internal/augment/active/item/powerfist/prepared
+ item = /obj/item/weapon/powerfist/prepared
diff --git a/code/modules/augment/implanter.dm b/code/modules/augment/implanter.dm
new file mode 100644
index 00000000000..68c4d28b940
--- /dev/null
+++ b/code/modules/augment/implanter.dm
@@ -0,0 +1,173 @@
+/obj/item/device/augment_implanter
+ name = "augment autodoc"
+ desc = "An oblong box with an irregular shape and a seam running down the center."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "compact_bionic_module"
+ w_class = ITEM_SIZE_NORMAL
+ origin_tech = list(TECH_DATA = 3, TECH_ESOTERIC = 3)
+ var/obj/item/organ/internal/augment/augment
+
+ /// If not falsy, skip the messy installation and just install the augment
+ var/instant
+
+ /// Transient value to block multiple activations at the same time
+ var/working
+
+
+/obj/item/device/augment_implanter/Initialize()
+ . = ..()
+ if (ispath(augment))
+ augment = new augment (src)
+
+
+/obj/item/device/augment_implanter/examine(mob/user)
+ . = ..()
+ if (isobserver(user) || (user.mind && user.mind.special_role != null) || user.skill_check(SKILL_DEVICES, SKILL_PROF))
+ to_chat(user, "A single-use augment installer with no medical knowledge necessary! " + SPAN_DANGER("Painkillers not included!"))
+ if (isnull(augment))
+ to_chat(user, "It seems to be empty.")
+ return
+ to_chat(user, SPAN_BOLD("It contains:"))
+ augment.examine(user)
+
+
+/obj/item/device/augment_implanter/attackby(obj/item/I, mob/living/user)
+ if (isCrowbar(I) && augment)
+ user.visible_message(
+ SPAN_ITALIC("\The [user] starts to remove \the [augment] from \the [src]."),
+ SPAN_WARNING("You start to remove \the [augment] from \the [src]."),
+ SPAN_ITALIC("You hear metal creaking.")
+ )
+ playsound(user, 'sound/items/Crowbar.ogg', 50, TRUE)
+ if (!do_after(user, 10 SECONDS, src) || !augment)
+ return
+ user.visible_message(
+ SPAN_ITALIC("\The [user] removes \the [augment] from \the [src]."),
+ SPAN_WARNING("You remove \the [augment] from \the [src]."),
+ SPAN_ITALIC("You hear a clunk.")
+ )
+ playsound(user, 'sound/items/Deconstruct.ogg', 50, TRUE)
+ user.put_in_hands(augment)
+ augment = null
+ return
+ ..()
+
+
+/obj/item/device/augment_implanter/attack_self(mob/living/carbon/human/user)
+ if (working)
+ return
+ if (!istype(user))
+ return
+ if (!augment)
+ to_chat(user, SPAN_WARNING("\The [src] is empty."))
+ return
+ if (!ishuman(user))
+ to_chat(user, SPAN_WARNING("\The [src] is incompatible with you."))
+ return
+ var/target_zone = user.zone_sel.selecting
+ if (!target_zone)
+ return
+ var/obj/item/organ/external/parent = user.get_organ(target_zone)
+ if (!parent)
+ to_chat(user, SPAN_WARNING("You don't have \a [target_zone]!"))
+ return
+ var/flavor = (parent.status & ORGAN_ROBOTIC) ? 1 : (parent.status & ORGAN_CRYSTAL) ? 2 : 0
+ if (flavor == 0 && !(augment.augment_flags & AUGMENT_BIOLOGICAL))
+ to_chat(user, SPAN_WARNING("\The [augment] cannot be installed in biological organs."))
+ return
+ if (flavor == 1 && !(augment.augment_flags & AUGMENT_MECHANICAL))
+ to_chat(user, SPAN_WARNING("\The [augment] cannot be installed in mechanical organs."))
+ return
+ if (flavor == 2 && !(augment.augment_flags & AUGMENT_CRYSTALINE))
+ to_chat(user, SPAN_WARNING("\The [augment] cannot be installed in crystaline organs."))
+ return
+ var/surgery_step = decls_repository.get_decl(/decl/surgery_step/internal/replace_organ)
+ if (augment.surgery_configure(user, user, parent, src, surgery_step))
+ return
+ var/occupied = user.internal_organs_by_name[augment.organ_tag]
+ if (occupied)
+ to_chat(user, SPAN_WARNING("You already have \an [occupied] installed there."))
+ return
+ if (flavor != -1)
+ var/old_loc = loc
+ var/proceed = alert(user, "This is going to hurt. Are you prepared?", "Woah there!", "I am!", "Wait...")
+ if (proceed != "I am!")
+ return
+ if (loc != old_loc)
+ return
+ var/success = instant
+ if (!instant)
+ working = TRUE
+ to_chat(user, SPAN_WARNING("\icon[src] Commencing procedure. " + SPAN_DANGER("Please remain calm.")))
+ user.visible_message(SPAN_WARNING("\The [user] places \his [parent.name] against \the [src]."))
+ if (!do_after(user, 2 SECONDS, src))
+ goto FailedAugmentImplant
+ user.visible_message(SPAN_DANGER("\The [src] purrs maliciously and unfurls its armatures with frightening speed!"))
+ if (flavor != 1)
+ user.custom_pain("Your [parent.name] feels like it's being shredded apart!", 160)
+ else
+ to_chat(user, SPAN_ITALIC("The access panel on your [parent.name] is torn open."))
+ playsound(user, 'sound/items/electronic_assembly_emptying.ogg', 50, TRUE)
+ parent.createwound(CUT, parent.min_broken_damage / 2, 1)
+ parent.clamp_organ()
+ parent.open_incision()
+ parent.fracture()
+ if (!do_after(user, 8 SECONDS, src))
+ goto FailedAugmentImplant
+ user.visible_message(SPAN_DANGER("\The [src] begins to insert its payload into \the [user]'s [parent.name]!"))
+ if (flavor != 1)
+ user.custom_pain("You feel something rooting around violently inside your [parent.name]!", 160)
+ else
+ to_chat(user, SPAN_ITALIC("Your [parent.name] shifts and twitches as \the [src] works."))
+ if (!flavor)
+ playsound(user, 'sound/effects/squelch1.ogg', 25, TRUE)
+ else
+ playsound(user, 'sound/items/jaws_pry.ogg', 50, TRUE)
+ if (!do_after(user, 8 SECONDS, src))
+ goto FailedAugmentImplant
+ user.visible_message(SPAN_WARNING("\The [src] withdraws from \the [user]'s [parent.name] and seals the [flavor != 1 ? "wound" : "hatch"]."))
+ if (!do_after(user, 2 SECONDS, src))
+ goto FailedAugmentImplant
+ parent.status &= ~ORGAN_BROKEN
+ parent.stage = 0
+ parent.update_wounds()
+ var/datum/wound/wound = parent.get_incision()
+ if (istype(wound))
+ wound.close()
+ if (parent.clamped())
+ parent.remove_clamps()
+ parent.update_wounds()
+ success = TRUE
+ FailedAugmentImplant:
+ working = FALSE
+ if (!success)
+ user.visible_message(SPAN_DANGER("\The [src] falls away from \the [user], leaving \his [parent.name] a mangled mess!"))
+ parent.take_general_damage(15)
+ return
+ to_chat(user, SPAN_WARNING("\icon[src] Procedure complete. ") + SPAN_NOTICE("Have a nice day."))
+ playsound(user, 'sound/machines/ping.ogg', 50, FALSE)
+ augment.forceMove(user)
+ augment.replaced(user, parent)
+ augment = null
+
+
+/obj/item/device/augment_implanter/iatric_monitor
+ augment = /obj/item/organ/internal/augment/active/iatric_monitor/hidden
+
+/obj/item/device/augment_implanter/wrist_blade
+ augment = /obj/item/organ/internal/augment/active/item/wrist_blade
+
+/obj/item/device/augment_implanter/popout_shotgun
+ augment = /obj/item/organ/internal/augment/active/item/popout_shotgun
+
+/obj/item/device/augment_implanter/nerve_dampeners
+ augment = /obj/item/organ/internal/augment/active/nerve_dampeners
+
+/obj/item/device/augment_implanter/adaptive_binoculars
+ augment = /obj/item/organ/internal/augment/active/item/adaptive_binoculars/hidden
+
+/obj/item/device/augment_implanter/engineering_toolset
+ augment = /obj/item/organ/internal/augment/active/polytool/engineer
+
+/obj/item/device/augment_implanter/powerfist
+ augment = /obj/item/organ/internal/augment/active/item/powerfist/prepared
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 30dbc5fbc3e..fac607940c3 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -231,3 +231,29 @@
icon_state = "rwelding-g"
item_state = "rwelding-g"
tint = TINT_MODERATE
+
+/obj/item/clothing/glasses/glare_dampeners
+ name = "glare dampeners"
+ desc = "Synthetic lenses over the eyes, protecting from bright lights."
+ icon_state = "welding-g"
+ item_state = "welding-g"
+ use_alt_layer = TRUE
+ flash_protection = FLASH_PROTECTION_MODERATE
+ darkness_view = -1
+
+/obj/item/clothing/glasses/augment_binoculars
+ name = "adaptive binoculars"
+ desc = "Digital lenses covering the eyes, capable of zooming in on distant targets."
+ gender = PLURAL
+ icon_state = "thermal"
+ item_state = "glasses"
+ action_button_name = "Toggle zoom"
+ zoomdevicename = "lenses"
+ electric = TRUE
+ unacidable = TRUE
+
+/obj/item/clothing/glasses/augment_binoculars/attack_self(mob/user)
+ if(zoom)
+ unzoom(user)
+ else
+ zoom(user)
From bdcca661141c16ef068e70e974d37879fa56bed0 Mon Sep 17 00:00:00 2001
From: BurpleBineapple <67706292+BurpleBineapple@users.noreply.github.com>
Date: Mon, 4 Apr 2022 15:10:48 -0400
Subject: [PATCH 9/9] removes bad argument
---
code/modules/augment/active/iatric_monitor.dm | 4 ++--
code/modules/augment/active/leukocyte_breeder.dm | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/augment/active/iatric_monitor.dm b/code/modules/augment/active/iatric_monitor.dm
index 63b1a091112..3f8cb2b0a96 100644
--- a/code/modules/augment/active/iatric_monitor.dm
+++ b/code/modules/augment/active/iatric_monitor.dm
@@ -11,14 +11,14 @@
. = ..()
if (severity)
var/scan_results = medical_scan_results(owner, TRUE, SKILL_NONE)
- owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20)
to_chat(owner, "
[scan_results]
")
to_chat(owner, SPAN_WARNING("Your [name] cheerily outputs a bogus report as it malfunctions."))
/obj/item/organ/internal/augment/active/iatric_monitor/activate()
var/scan_results = medical_scan_results(owner, TRUE, SKILL_PROF)
- owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20)
to_chat(owner, "
[scan_results]
")
diff --git a/code/modules/augment/active/leukocyte_breeder.dm b/code/modules/augment/active/leukocyte_breeder.dm
index a01f9ae7326..aa29e738cb2 100644
--- a/code/modules/augment/active/leukocyte_breeder.dm
+++ b/code/modules/augment/active/leukocyte_breeder.dm
@@ -42,7 +42,7 @@
if (alert(owner, "Deactivate \the [src]?", name, "Yes", "No") != "Yes" || !can_activate())
return
active = !active
- owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20, is_global = TRUE)
+ owner.playsound_simple(null, 'sound/effects/fastbeep.ogg', 20)
if (active)
to_chat(owner, SPAN_NOTICE("Leukocyte breeder engaged and improving immune response."))
else