diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm
index a407bb9657e..d74adff7d5d 100644
--- a/code/__DEFINES/misc_defines.dm
+++ b/code/__DEFINES/misc_defines.dm
@@ -191,24 +191,25 @@
#define FOAM_REACT_BEFORE_SPREAD (1<<3)
//Human Overlays Indexes/////////
-#define EYES_OVERLAY_LAYER 50
-#define MISC_LAYER 49 // Handles eye_shine() -> cybernetic eyes, specific eye traits.
-#define WING_LAYER 48
-#define WING_UNDERLIMBS_LAYER 47
-#define MUTANTRACE_LAYER 46
-#define TAIL_UNDERLIMBS_LAYER 45 //Tail split-rendering.
-#define LIMBS_LAYER 44
-#define MARKINGS_LAYER 43
-#define INTORGAN_LAYER 42
-#define UNDERWEAR_LAYER 41
-#define MUTATIONS_LAYER 40
-#define H_DAMAGE_LAYER 39
-#define UNIFORM_LAYER 38
-#define ID_LAYER 37
-#define HANDS_LAYER 36 //Exists to overlay hands over jumpsuits
-#define SHOES_LAYER 35
-#define L_FOOT_BLOOD_LAYER 34 // Blood overlay separation Left-Foot
-#define R_FOOT_BLOOD_LAYER 33 // Blood overlay separation Right-Foot
+#define EYES_OVERLAY_LAYER 51
+#define MISC_LAYER 50 // Handles eye_shine() -> cybernetic eyes, specific eye traits.
+#define WING_LAYER 49
+#define WING_UNDERLIMBS_LAYER 48
+#define MUTANTRACE_LAYER 47
+#define TAIL_UNDERLIMBS_LAYER 46 //Tail split-rendering.
+#define LIMBS_LAYER 45
+#define MARKINGS_LAYER 44
+#define INTORGAN_LAYER 43
+#define UNDERWEAR_LAYER 42
+#define MUTATIONS_LAYER 41
+#define H_DAMAGE_LAYER 40
+#define UNIFORM_LAYER 39
+#define ID_LAYER 38
+#define HANDS_LAYER 37 //Exists to overlay hands over jumpsuits
+#define SHOES_LAYER 36
+#define L_FOOT_BLOOD_LAYER 35 // Blood overlay separation Left-Foot
+#define R_FOOT_BLOOD_LAYER 34 // Blood overlay separation Right-Foot
+#define HAND_INTORGAN_LAYER 33
#define GLOVES_LAYER 32
#define L_HAND_BLOOD_LAYER 31 // Blood overlay separation Left-Hand
#define R_HAND_BLOOD_LAYER 30 // Blood overlay separation Right-Hand
@@ -241,7 +242,7 @@
#define HALO_LAYER 3 //blood cult ascended halo, because there's currently no better solution for adding/removing
#define FIRE_LAYER 2 //If you're on fire
#define FROZEN_LAYER 1
-#define TOTAL_LAYERS 50
+#define TOTAL_LAYERS 51
///Access Region Codes///
#define REGION_ALL 0
diff --git a/code/game/objects/items/stacks/synthetic_skin.dm b/code/game/objects/items/stacks/synthetic_skin.dm
new file mode 100644
index 00000000000..82b1378dc6c
--- /dev/null
+++ b/code/game/objects/items/stacks/synthetic_skin.dm
@@ -0,0 +1,44 @@
+/obj/item/stack/synthetic_skin
+ name = "level-1 synthetic skin plate"
+ desc = "A sheet of level-1 synthetic skin plating. Used as a cheap covering for cybernetic organs, is able to match the colour of the limb but not the texture."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "skin_1"
+ w_class = WEIGHT_CLASS_SMALL
+ singular_name = "skin plate"
+ max_amount = 10
+ merge_type = /obj/item/stack/synthetic_skin
+ var/skin_level = 1
+
+/obj/item/stack/synthetic_skin/attack__legacy__attackchain(mob/living/M as mob, mob/user as mob)
+ if(!ishuman(M) || !istype(user))
+ return FALSE
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/external_limb = H.get_organ(user.zone_selected)
+ if(external_limb)
+ user.visible_message("[user] starts to apply [src] on [H]'s [external_limb.name]...")
+ if(!do_mob(user, H, 5 SECONDS))
+ return FALSE
+ use(1)
+ if(external_limb.apply_augmented_skin(skin_level))
+ user.visible_message("[user] applies some [src] on [H]'s [external_limb.name].")
+ return TRUE
+ else
+ to_chat(user, "You fail to apply a better skin cover to [H]'s [external_limb.name].")
+ return FALSE
+
+/obj/item/stack/synthetic_skin/level_2
+ name = "level-2 synthetic skin patch"
+ desc = "A sealed patch of synthetic skin. An improvement over the basic version, more water resistant and less prone to peeling off."
+ icon_state = "skin_2"
+ merge_type = /obj/item/stack/synthetic_skin/level_2
+ singular_name = "skin patch"
+ skin_level = 2
+
+
+/obj/item/stack/synthetic_skin/level_3
+ name = "level-3 synthetic skin foam"
+ desc = "A nanite foam injector meeting the requirements of level-3 synthetic skin. The best one can buy, best used to hide major cybernetic alterations, for beauty or for infiltration."
+ icon_state = "skin_3"
+ merge_type = /obj/item/stack/synthetic_skin/level_3
+ singular_name = "nanite foam"
+ skin_level = 3
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index f9aaef94fb6..4cc16ad2a2b 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -155,6 +155,7 @@
new /obj/item/stack/cable_coil(src)
new /obj/item/stack/cable_coil(src)
new /obj/item/robotanalyzer(src)
+ new /obj/item/stack/synthetic_skin(src, 3)
/obj/item/storage/firstaid/machine/empty/populate_contents()
return
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 5015bf2d994..5411923516d 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -875,3 +875,11 @@ emp_act
to_contaminate -= to_contaminate[1]
for(var/atom/thing in to_contaminate)
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)
+
+/mob/living/carbon/human/proc/peel_off_synthetic_skin()
+ var/obj/item/organ/external/external_limb = get_organ(zone_selected)
+ if(external_limb && external_limb.augmented_skin_cover_level)
+ visible_message("[src] begins to pull at their skin...")
+ if(!do_mob(src, src, 5 SECONDS))
+ return
+ external_limb.break_augmented_skin(TRUE)
diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm
index d44871697cd..711fa84aae2 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -1356,6 +1356,20 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[INTORGAN_LAYER] = standing
apply_overlay(INTORGAN_LAYER)
+ update_hand_int_organs()
+
+/mob/living/carbon/human/proc/update_hand_int_organs()
+ remove_overlay(HAND_INTORGAN_LAYER)
+
+ var/list/standing = list()
+ for(var/organ in internal_organs)
+ var/obj/item/organ/internal/I = organ
+ var/extra_render = I.extra_render()
+ if(extra_render)
+ standing += extra_render
+
+ overlays_standing[HAND_INTORGAN_LAYER] = standing
+ apply_overlay(HAND_INTORGAN_LAYER)
/mob/living/carbon/human/handle_transform_change()
..()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 7f41a8ef6e1..a924c29823d 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -294,7 +294,11 @@
// End BS12 momentum-transfer code.
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE)
- if(user == src || anchored)
+ if(user == src && ishuman(user))
+ var/mob/living/carbon/human/self = user
+ INVOKE_ASYNC(self, TYPE_PROC_REF(/mob/living/carbon/human, peel_off_synthetic_skin))
+ return
+ if(anchored)
return FALSE
if(!(status_flags & CANPUSH))
return FALSE
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 3369b429aee..33a0c93b6a4 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -174,6 +174,39 @@
build_path = /obj/item/stack/nanopaste
category = list("Medical")
+/datum/design/skin_1
+ name = "level-1 synthetic skin plate"
+ desc = "A sheet of level-1 synthetic skin plating. Used as a cheap covering for cybernetic organs, is able to match the colour of the limb but not the texture."
+ id = "skin_1"
+ req_tech = list("biotech" = 1, "materials" = 1)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 20
+ materials = list(MAT_METAL = 1000, MAT_GLASS = 500)
+ build_path = /obj/item/stack/synthetic_skin
+ category = list("Medical")
+
+/datum/design/skin_2
+ name = "level-2 synthetic skin patch"
+ desc = "A sealed patch of synthetic skin. An improvement over the basic version, more water resistant and less prone to peeling off."
+ id = "skin_2"
+ req_tech = list("biotech" = 5, "materials" = 5)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 40
+ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000, MAT_TITANIUM = 250)
+ build_path = /obj/item/stack/synthetic_skin/level_2
+ category = list("Medical")
+
+/datum/design/skin_3
+ name = "level-3 synthetic skin foam"
+ desc = "A nanite foam injector meeting the requirements of level-3 synthetic skin. The best one can buy, best used to hide major cybernetic alterations, for beauty or for infiltration."
+ id = "skin_3"
+ req_tech = list("biotech" = 7, "materials" = 7)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 60
+ materials = list(MAT_METAL = 2500, MAT_GLASS = 2000, MAT_TITANIUM = 500, MAT_BLUESPACE = 250)
+ build_path = /obj/item/stack/synthetic_skin/level_3
+ category = list("Medical")
+
/datum/design/reagent_scanner
name = "Reagent Scanner"
desc = "A device for identifying chemicals."
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index d04f2b78897..a8cb43c31a3 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -14,6 +14,7 @@
var/obj/item/holder = null
// You can use this var for item path, it would be converted into an item on New()
+
/obj/item/organ/internal/cyberimp/arm/New()
..()
if(ispath(holder))
@@ -66,6 +67,34 @@
Retract()
..()
+/obj/item/organ/internal/cyberimp/arm/proc/get_overlay_state(image_layer)
+ return "[augment_icon][parent_organ == BODY_ZONE_L_ARM ? "_left" : "_right"]"
+
+/obj/item/organ/internal/cyberimp/arm/render()
+ . = ..()
+ if(!.)
+ return
+
+ var/mutable_appearance/arm_overlay = mutable_appearance(
+ icon = augment_state,
+ icon_state = get_overlay_state(),
+ layer = -INTORGAN_LAYER,
+ )
+ return arm_overlay
+
+/obj/item/organ/internal/cyberimp/arm/extra_render()
+ . = ..()
+ if(!.)
+ return
+ var/mutable_appearance/hand_overlay = mutable_appearance(
+ icon = augment_state,
+ icon_state = "[get_overlay_state()]_hand",
+ layer = -HAND_INTORGAN_LAYER,
+ )
+ return hand_overlay
+
+
+
/obj/item/organ/internal/cyberimp/arm/proc/retract_to_linked_implant()
SIGNAL_HANDLER
if(holder && holder == owner.get_active_hand())
@@ -231,6 +260,8 @@
contents = newlist(/obj/item/screwdriver/cyborg, /obj/item/wrench/cyborg, /obj/item/weldingtool/largetank/cyborg,
/obj/item/crowbar/cyborg, /obj/item/wirecutters/cyborg, /obj/item/multitool/cyborg)
actions_types = list(/datum/action/item_action/organ_action/toggle/utility_belt)
+ augment_icon = "toolkit_engi"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/toolset/l
parent_organ = "l_arm"
@@ -253,6 +284,8 @@
origin_tech = "materials=5;engineering=5;plasmatech=5;powerstorage=4;abductor=3"
contents = newlist(/obj/item/screwdriver/abductor, /obj/item/wirecutters/abductor, /obj/item/crowbar/abductor, /obj/item/wrench/abductor, /obj/item/weldingtool/abductor, /obj/item/multitool/abductor)
actions_types = list(/datum/action/item_action/organ_action/toggle/abductor_belt)
+ augment_icon = "toolkit_engi"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/toolset_abductor/l
parent_organ = "l_arm"
@@ -268,6 +301,8 @@
origin_tech = "materials=5;engineering=5;biotech=5;powerstorage=4;abductor=2"
contents = newlist(/obj/item/mop/advanced/abductor, /obj/item/soap/syndie/abductor, /obj/item/lightreplacer/bluespace/abductor, /obj/item/holosign_creator/janitor, /obj/item/melee/flyswatter/abductor, /obj/item/reagent_containers/spray/cleaner/safety/abductor)
actions_types = list(/datum/action/item_action/organ_action/toggle/abductor_belt)
+ augment_icon = "toolkit_jani"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/janitorial_abductor/l
parent_organ = "l_arm"
@@ -279,6 +314,8 @@
origin_tech = "materials=5;engineering=5;plasmatech=5;powerstorage=4;abductor=2"
contents = newlist(/obj/item/retractor/alien, /obj/item/hemostat/alien, /obj/item/bonesetter/alien, /obj/item/scalpel/laser/alien, /obj/item/circular_saw/alien, /obj/item/bonegel/alien, /obj/item/fix_o_vein/alien, /obj/item/surgicaldrill/alien)
actions_types = list(/datum/action/item_action/organ_action/toggle/abductor_belt)
+ augment_icon = "toolkit_med"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/surgical_abductor/l
parent_organ = "l_arm"
@@ -297,8 +334,11 @@
name = "integrated medical beamgun"
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
contents = newlist(/obj/item/gun/medbeam)
+ icon_state = "toolkit_surgical"
origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1"
actions_types = list(/datum/action/item_action/organ_action/toggle/medibeam)
+ augment_icon = "toolkit_med"
+ do_extra_render = TRUE
/datum/action/item_action/organ_action/toggle/flash
button_icon = 'icons/obj/device.dmi'
@@ -310,6 +350,8 @@
contents = newlist(/obj/item/flash/armimplant)
origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3"
actions_types = list(/datum/action/item_action/organ_action/toggle/flash)
+ augment_icon = "toolkit"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/flash/New()
..()
@@ -322,6 +364,8 @@
desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
contents = newlist(/obj/item/borg/stun)
origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3"
+ augment_icon = "toolkit"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/combat
name = "combat cybernetics implant"
@@ -355,6 +399,8 @@
contents = newlist(/obj/item/retractor/augment, /obj/item/hemostat/augment, /obj/item/cautery/augment, /obj/item/bonesetter/augment, /obj/item/scalpel/augment, /obj/item/circular_saw/augment, /obj/item/bonegel/augment, /obj/item/fix_o_vein/augment, /obj/item/surgicaldrill/augment)
origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3"
actions_types = list(/datum/action/item_action/organ_action/toggle/dufflebag_med)
+ augment_icon = "toolkit_med"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/surgery/l
parent_organ = "l_arm"
@@ -371,6 +417,8 @@
contents = newlist(/obj/item/mop/advanced, /obj/item/soap, /obj/item/lightreplacer, /obj/item/holosign_creator/janitor, /obj/item/melee/flyswatter, /obj/item/reagent_containers/spray/cleaner/safety)
origin_tech = "materials=3;engineering=4;biotech=3"
actions_types = list(/datum/action/item_action/organ_action/toggle/janibelt)
+ augment_icon = "toolkit_jani"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/janitorial/l
parent_organ = "l_arm"
@@ -401,6 +449,8 @@
contents = newlist(/obj/item/plant_analyzer, /obj/item/cultivator, /obj/item/hatchet, /obj/item/shovel/spade, /obj/item/reagent_containers/spray/weedspray, /obj/item/reagent_containers/spray/pestspray)
origin_tech = "materials=3;engineering=4;biotech=3"
actions_types = list(/datum/action/item_action/organ_action/toggle/botanybelt)
+ augment_icon = "toolkit_hydro"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/botanical/l
parent_organ = "l_arm"
@@ -498,6 +548,8 @@
contents = newlist(/obj/item/melee/classic_baton)
actions_types = list(/datum/action/item_action/organ_action/toggle/telebaton)
+ augment_icon = "toolkit"
+ do_extra_render = TRUE
/datum/action/item_action/organ_action/toggle/advanced_mop
button_icon = 'icons/obj/janitor.dmi'
@@ -506,9 +558,12 @@
/obj/item/organ/internal/cyberimp/arm/advmop
name = "advanced mop implant"
desc = "Advanced mop implant. Does what it says on the tin" // A better description
+ icon_state = "toolkit_janitor"
contents = newlist(/obj/item/mop/advanced)
actions_types = list(/datum/action/item_action/organ_action/toggle/advanced_mop)
+ augment_icon = "toolkit_jani"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/cargo
name = "integrated cargo implant"
@@ -620,6 +675,8 @@
actions_types = list(/datum/action/item_action/organ_action/toggle/razorwire)
origin_tech = "combat=5;biotech=5;syndicate=2"
stealth_level = 1 // Hidden from health analyzers
+ augment_icon = "razor" // Note: By default the autosurgeons apply the highest level of cover plating.
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/razorwire/examine_more(mob/user)
. = ..()
@@ -674,6 +731,8 @@
contents = newlist(/obj/item/gun/projectile/revolver/doublebarrel/shell_launcher)
icon_state = "shell_cannon"
actions_types = list(/datum/action/item_action/organ_action/toggle/shell_cannon)
+ augment_icon = "razor"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/shell_launcher/emp_act(severity)
if(!owner)
@@ -737,6 +796,8 @@
contents = newlist(/obj/item/shield/v1_arm)
actions_types = list(/datum/action/item_action/organ_action/toggle/v1_arm)
+ augment_icon = "v1_arm"
+ do_extra_render = TRUE
var/disabled = FALSE
/obj/item/organ/internal/cyberimp/arm/v1_arm/emp_act(severity)
@@ -757,6 +818,15 @@
return FALSE
..()
+/obj/item/organ/internal/cyberimp/arm/v1_arm/render()
+ if(isvox(owner))
+ augment_icon = "v1_arm_vox"
+ else if(isdrask(owner))
+ augment_icon = "v1_arm_drask"
+ else
+ augment_icon = "v1_arm"
+ return ..()
+
/obj/item/shield/v1_arm
name = "vortex feedback arm"
desc = "A modification to a users arm, allowing them to use a vortex core energy feedback, to parry, reflect, and even empower projectile attacks. Rumors that it runs on the user's blood are unconfirmed."
@@ -865,6 +935,7 @@
slot = "l_arm_device"
actions_types = list()
+ augment_icon = "strongarm"
var/datum/martial_art/muscle_implant/muscle_implant
/obj/item/organ/internal/cyberimp/arm/muscle/Initialize(mapload)
@@ -962,6 +1033,8 @@
contents = newlist(/obj/item/melee/mantis_blade/syndicate)
icon_state = "syndie_mantis"
icon = 'icons/obj/weapons/melee.dmi'
+ augment_icon = "razor"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/syndie_mantis/l
parent_organ = "l_arm"
@@ -973,6 +1046,8 @@
contents = newlist(/obj/item/melee/mantis_blade/nt)
icon_state = "mantis"
icon = 'icons/obj/weapons/melee.dmi'
+ augment_icon = "razor"
+ do_extra_render = TRUE
/obj/item/organ/internal/cyberimp/arm/nt_mantis/l
parent_organ = "l_arm"
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 370e8aa97f9..730f50d7606 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -6,6 +6,7 @@
var/implant_overlay
var/crit_fail = FALSE //Used by certain implants to disable them.
tough = TRUE // Immune to damage
+ augment_state ='icons/mob/human_races/robotic.dmi'
/obj/item/organ/internal/cyberimp/New(mob/M = null)
. = ..()
@@ -330,6 +331,8 @@
emp_proof = TRUE
actions_types = list(/datum/action/item_action/organ_action/toggle/sensory_enhancer)
origin_tech = "combat=6;biotech=6;syndicate=4"
+ augment_icon = "sandy"
+ always_show_augment = TRUE // A bit too big and bright to hide with synthetic skin.
///The icon state used for the on mob sprite. Default is sandy. Drask and vox have their own unique sprites
var/custom_mob_sprite = "sandy"
COOLDOWN_DECLARE(sensory_enhancer_cooldown)
@@ -363,13 +366,16 @@
REMOVE_TRAIT(M, TRAIT_MEPHEDRONE_ADAPTED, "[UID()]")
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/render()
+ . = ..()
+ if(!.)
+ return
if(isvox(owner))
custom_mob_sprite = "vox_sandy"
else if(isdrask(owner))
custom_mob_sprite = "drask_sandy"
else
custom_mob_sprite = "sandy"
- var/mutable_appearance/our_MA = mutable_appearance('icons/mob/human_races/robotic.dmi', icon_state, layer = -INTORGAN_LAYER)
+ var/mutable_appearance/our_MA = mutable_appearance(augment_state, custom_mob_sprite, layer = -INTORGAN_LAYER)
return our_MA
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/emp_act(severity)
@@ -581,6 +587,14 @@
slot = "breathing_tube"
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=2;biotech=3"
+ augment_icon = "breathing_tube"
+
+/obj/item/organ/internal/cyberimp/mouth/breathing_tube/render()
+ . = ..()
+ if(!.)
+ return
+ var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
+ return our_MA
/obj/item/organ/internal/cyberimp/mouth/breathing_tube/emp_act(severity)
if(emp_proof)
@@ -607,6 +621,7 @@
var/disabled_by_emp = FALSE
slot = "stomach"
origin_tech = "materials=2;powerstorage=2;biotech=2"
+ augment_icon = "nutripump"
/obj/item/organ/internal/cyberimp/chest/nutriment/examine(mob/user)
. = ..()
@@ -646,6 +661,14 @@
synthesizing = FALSE
addtimer(CALLBACK(src, PROC_REF(emp_cool)), 60 SECONDS)
+/obj/item/organ/internal/cyberimp/chest/nutriment/render()
+ . = ..()
+ if(!.)
+ return
+ var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
+ return our_MA
+
+
/obj/item/organ/internal/cyberimp/chest/nutriment/plus
name = "Nutriment pump implant PLUS"
desc = "This implant will synthesize a small amount of nutriment and pumps it directly into your bloodstream when you are hungry."
@@ -653,6 +676,7 @@
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
origin_tech = "materials=4;powerstorage=3;biotech=3"
+ augment_icon = "nutripump_adv"
/obj/item/organ/internal/cyberimp/chest/nutriment/hardened
name = "hardened nutriment pump implant"
@@ -669,6 +693,7 @@
implant_overlay = null
origin_tech = "materials=5;programming=5;biotech=6"
slot = "heartdrive"
+ augment_icon = "reviver"
/// How long the implant will go on cooldown for once the user has exited crit, in seconds.
var/revive_cost = 0 SECONDS
/// Are we in the progress of healing the user?
@@ -692,6 +717,13 @@
. = ..()
desc += " The implant has been hardened. It is invulnerable to EMPs."
+/obj/item/organ/internal/cyberimp/chest/reviver/render()
+ . = ..()
+ if(!.)
+ return
+ var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
+ return our_MA
+
/obj/item/organ/internal/cyberimp/chest/reviver/dead_process()
try_heal() // Allows implant to work even on dead people
diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm
index 177ab68ed39..a3121e6998a 100644
--- a/code/modules/surgery/organs/autosurgeon.dm
+++ b/code/modules/surgery/organs/autosurgeon.dm
@@ -110,6 +110,11 @@
name = "suspicious implant autosurgeon"
icon_state = "syndicate_autoimplanter"
+/obj/item/autosurgeon/organ/syndicate/attack_self__legacy__attackchain(mob/user)
+ if(storedorgan && uses && storedorgan.is_robotic()) // Helps keep the syndicate ones hidden. One can peel them off if they want them to be visable.
+ storedorgan.self_augmented_skin_level = 3
+ return ..()
+
/obj/item/autosurgeon/organ/syndicate/oneuse
uses = 1
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index 2e020896125..c8382c1f7f6 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -63,6 +63,8 @@
var/splinted_count = 0 //Time when this organ was last splinted
///If this organ's max HP is reduced by the IPC magnetic joints implant
var/fragile = FALSE
+ ///The level of false skin used to cover robotic organs on the limb. Updated when too damaged, when installed, or when an organ with it is installed.
+ var/augmented_skin_cover_level = 0
/obj/item/organ/external/necrotize(update_sprite=TRUE, ignore_vital_death = FALSE)
if(status & (ORGAN_ROBOT|ORGAN_DEAD))
@@ -241,6 +243,8 @@
check_for_internal_bleeding(brute)
// See if we need to inflict severe burns
check_for_burn_wound(burn)
+ // See what happens to the skin covers.
+ check_skin_covers(brute, burn)
// Threshold needed to have a chance of hurting internal bits with something sharp
#define LIMB_SHARP_THRESH_INT_DMG 5
// Threshold needed to have a chance of hurting internal bits
@@ -538,6 +542,15 @@ Note that amputating the affected organ does in fact remove the infection from t
if(burn_dam >= min_broken_damage && prob(damage * max(owner.bodytemperature / BODYTEMP_HEAT_DAMAGE_LIMIT, 1)))
cause_burn_wound(update_health)
+/obj/item/organ/external/proc/check_skin_covers(brute, burn)
+ if(!augmented_skin_cover_level || augmented_skin_cover_level == 4) // No need to run it if they don't have it, or if it is unbreakable.
+ return
+ if(((brute_dam >= min_broken_damage && brute) || (burn_dam >= min_broken_damage && burn)) && augmented_skin_cover_level == 1) // We want this at 50% for arms / feet which have low max hp, 35% for head / chest
+ break_augmented_skin()
+ return
+ if((brute_dam >= max_damage * (augmented_skin_cover_level / 3) && brute) || (burn_dam >= max_damage * (augmented_skin_cover_level / 3) && burn)) // 66% for level 2, 100% for level 3
+ break_augmented_skin()
+
// new damage icon system
// returns just the brute/burn damage code
/obj/item/organ/external/proc/damage_state_text()
@@ -814,6 +827,31 @@ Note that amputating the affected organ does in fact remove the infection from t
if(update_health)
owner.updatehealth("burn wound fixed")
+/obj/item/organ/external/proc/break_augmented_skin(intentional = FALSE)
+ augmented_skin_cover_level = 0
+ if(!owner)
+ return
+ playsound(owner.loc, 'sound/items/poster_ripped.ogg', 50, TRUE)
+ if(!intentional)
+ owner.visible_message("Synthetic skin shatters and flakes off [owner]'s [name]!",
+ "Your synthetic skin fails on your [name]!")
+ else
+ owner.visible_message("[owner] tears their synthetic skin off their [name], exposing the cybernetics beneath!",
+ "You peel your synthetic skin off your cybernetics on your [name].")
+ if(ishuman(owner))
+ var/mob/living/carbon/human/refreshing = owner
+ refreshing.update_int_organs()
+
+/obj/item/organ/external/proc/apply_augmented_skin(applied_level)
+ if(applied_level + is_robotic() <= augmented_skin_cover_level) // Don't do anything if the application matches or is below the current level.
+ return FALSE
+ augmented_skin_cover_level = (applied_level + is_robotic()) // Robotic limbs get an extra level of protection.
+ if(!owner || !ishuman(owner))
+ return TRUE
+ var/mob/living/carbon/human/refreshing = owner
+ refreshing.update_int_organs()
+ return TRUE
+
/obj/item/organ/external/robotize(company, make_tough = FALSE, convert_all = TRUE)
..()
//robot limbs take reduced damage
@@ -821,6 +859,8 @@ Note that amputating the affected organ does in fact remove the infection from t
dismember_at_max_damage = TRUE
else
tough = TRUE
+ if(augmented_skin_cover_level)
+ apply_augmented_skin(augmented_skin_cover_level) // Raises it a level
// Robot parts also lack bones
// This is so surgery isn't kaput, let's see how this does
encased = null
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 71656876a6e..e24d5bf3a58 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -20,6 +20,16 @@
var/is_xeno_organ = FALSE
/// Does this organ give a warning upon being inserted?
var/warning = FALSE
+ /// Does this organ show outside the mob, and what is the icon state?
+ var/augment_state = null
+ /// Does this organ actually have a sprite for it being on the arm? And what is the path of it.
+ var/augment_icon = null
+ /// Does this organ have a extra render mechanic?
+ var/do_extra_render = FALSE
+ /// Does this organ ignore skin covers?
+ var/always_show_augment = FALSE
+ /// Does this organ have augmented skin to apply to the user on install? If so, apply it to the user and remove it.
+ var/self_augmented_skin_level = 0
/obj/item/organ/internal/New(mob/living/carbon/holder)
..()
@@ -49,6 +59,8 @@
. = ..()
if(is_xeno_organ)
. += "It looks like it would replace \the [slot]."
+ if(self_augmented_skin_level)
+ . += "It seems to have level-[self_augmented_skin_level] synthetic skin applied."
/obj/item/organ/internal/proc/insert(mob/living/carbon/M, special = 0, dont_remove_slot = 0)
if(!iscarbon(M) || owner == M)
@@ -80,6 +92,9 @@
stack_trace("[src] attempted to insert into a [parent_organ], but [parent_organ] wasn't an organ! [atom_loc_line(M)]")
else
parent.internal_organs |= src
+ if(self_augmented_skin_level)
+ parent.apply_augmented_skin(self_augmented_skin_level)
+ self_augmented_skin_level = 0
loc = null
for(var/X in actions)
var/datum/action/A = X
@@ -218,7 +233,27 @@
// Rendering!
/obj/item/organ/internal/proc/render()
- return
+ if(!augment_state || !augment_icon || !owner)
+ return FALSE
+ var/obj/item/organ/external/our_parent = owner.get_organ(parent_organ)
+ if(!our_parent) // I don't know how you pulled that off, let us be safe.
+ return FALSE
+ if(our_parent.augmented_skin_cover_level && !always_show_augment)
+ return FALSE
+
+ return TRUE
+
+// An extra render used in certain situations.
+/obj/item/organ/internal/proc/extra_render()
+ if(!augment_state || !augment_icon || !owner || !do_extra_render)
+ return FALSE
+ var/obj/item/organ/external/our_parent = owner.get_organ(parent_organ)
+ if(!our_parent) // I don't know how you pulled that off, let us be safe.
+ return FALSE
+ if(our_parent.augmented_skin_cover_level && !always_show_augment)
+ return FALSE
+
+ return TRUE
/obj/item/organ/internal/attack__legacy__attackchain(mob/living/carbon/M, mob/user)
if(M == user && ishuman(user))
@@ -235,6 +270,16 @@
else
..()
+/obj/item/organ/internal/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+ if(is_robotic() && istype(I, /obj/item/stack/synthetic_skin))
+ var/obj/item/stack/synthetic_skin/skin = I
+ skin.use(1)
+ self_augmented_skin_level = skin.skin_level
+ to_chat(user, "You apply [skin] to [src].")
+ return
+ return ..()
+
+
/****************************************************
INTERNAL ORGANS DEFINES
****************************************************/
diff --git a/icons/mob/human_races/robotic.dmi b/icons/mob/human_races/robotic.dmi
index 7fe9926b98a..27ceb7e1978 100644
Binary files a/icons/mob/human_races/robotic.dmi and b/icons/mob/human_races/robotic.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index b54b4652cc7..051247ebb3d 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 553f0cd42d0..5ba9d08c69b 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1373,6 +1373,7 @@
#include "code\game\objects\items\stacks\seaweed.dm"
#include "code\game\objects\items\stacks\stack.dm"
#include "code\game\objects\items\stacks\stack_recipe.dm"
+#include "code\game\objects\items\stacks\synthetic_skin.dm"
#include "code\game\objects\items\stacks\telecrystal.dm"
#include "code\game\objects\items\stacks\sheets\glass.dm"
#include "code\game\objects\items\stacks\sheets\leather.dm"