diff --git a/code/__DEFINES/~skyrat_defines/DNA.dm b/code/__DEFINES/~skyrat_defines/DNA.dm
index a083fa20c98..6395d5af712 100644
--- a/code/__DEFINES/~skyrat_defines/DNA.dm
+++ b/code/__DEFINES/~skyrat_defines/DNA.dm
@@ -1,15 +1,25 @@
-//We start from 10 to not interfere with TG species defines, should they add more
+//We start from 30 to not interfere with TG species defines, should they add more
/// We're using all three mutcolor features for our skin coloration
-#define MUTCOLOR_MATRIXED 10
-#define MUTCOLORS2 11
-#define MUTCOLORS3 12
+#define MUTCOLOR_MATRIXED 30
+#define MUTCOLORS2 31
+#define MUTCOLORS3 32
// Defines for whether an accessory should have one or three colors to choose for
-#define USE_ONE_COLOR 11
-#define USE_MATRIXED_COLORS 12
+#define USE_ONE_COLOR 31
+#define USE_MATRIXED_COLORS 32
+// Defines for some extra species traits
+#define REVIVES_BY_HEALING 33
+#define ROBOTIC_LIMBS 34
+#define ROBOTIC_DNA_ORGANS 35
//Also.. yes for some reason specie traits and accessory defines are together
-//Some defines for sprite accessories
+//Defines for processing reagents, for synths, IPC's and Vox
+#define PROCESS_ORGANIC 1 //Only processes reagents with "ORGANIC" or "ORGANIC | SYNTHETIC"
+#define PROCESS_SYNTHETIC 2 //Only processes reagents with "SYNTHETIC" or "ORGANIC | SYNTHETIC"
+#define REAGENT_ORGANIC 1
+#define REAGENT_SYNTHETIC 2
+
+//Some defines for sprite accessories
// Which color source we're using when the accessory is added
#define DEFAULT_PRIMARY 1
#define DEFAULT_SECONDARY 2
diff --git a/code/__DEFINES/~skyrat_defines/traits.dm b/code/__DEFINES/~skyrat_defines/traits.dm
index e8581b0f667..f8dab37da15 100644
--- a/code/__DEFINES/~skyrat_defines/traits.dm
+++ b/code/__DEFINES/~skyrat_defines/traits.dm
@@ -1 +1,3 @@
+// Defines for some extra traits
+#define TRAIT_NO_HUSK "no_husk"
#define TRAIT_NORUNNING "norunning" // You walk!
diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
index 046c7249a17..d648216f845 100644
--- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
@@ -23,6 +23,7 @@
name = R.glass_name
desc = R.glass_desc
if(R.glass_icon_state)
+ icon = R.glass_icon || 'icons/obj/drinks.dmi' //SKYRAT EDIT ADDITION - CUSTOMIZATION
icon_state = R.glass_icon_state
else
var/mutable_appearance/reagent_overlay = mutable_appearance(icon, "glassoverlay")
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 6a85c5e63b6..9d87bb91aeb 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -465,6 +465,8 @@
to_chat(src, "You feel your heart beating again!")
electrocution_animation(40)
+//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular)
+/*
/mob/living/carbon/human/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_CONTENTS)
@@ -482,6 +484,8 @@
if(2)
L.receive_damage(0,5)
Paralyze(100)
+*/
+//SKYRAT EDIT REMOVAL END
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc
var/list/damaged = list()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index b50ae94c897..0d7461094ef 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -466,7 +466,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/dynamic_fhair_suffix = ""
//for augmented heads
- if(HD.status == BODYPART_ROBOTIC)
+ if(HD.status == BODYPART_ROBOTIC && !(ROBOTIC_LIMBS in species_traits)) //SKYRAT EDIT CHANGE - CUSTOMIZATION
return
//we check if our hat or helmet hides our facial hair.
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index fdac65e20f2..d2c6de76227 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -376,6 +376,29 @@
if(!C)
C = R.holder.my_atom
+ //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
+ if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ //Check if this mob's species is set and can process this type of reagent
+ var/can_process = FALSE
+ //If we somehow avoided getting a species or reagent_flags set, we'll assume we aren't meant to process ANY reagents
+ if(H.dna && H.dna.species.reagent_flags)
+ var/owner_flags = H.dna.species.reagent_flags
+ if((R.process_flags & REAGENT_SYNTHETIC) && (owner_flags & PROCESS_SYNTHETIC)) //SYNTHETIC-oriented reagents require PROCESS_SYNTHETIC
+ can_process = TRUE
+ if((R.process_flags & REAGENT_ORGANIC) && (owner_flags & PROCESS_ORGANIC)) //ORGANIC-oriented reagents require PROCESS_ORGANIC
+ can_process = TRUE
+
+ //If the mob can't process it, remove the reagent at it's normal rate without doing any addictions, overdoses, or on_mob_life() for the reagent
+ if(!can_process)
+ R.holder.remove_reagent(R.type, R.metabolization_rate)
+ continue
+ //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption)
+ else
+ if(R.process_flags == REAGENT_SYNTHETIC)
+ R.holder.remove_reagent(R.type, R.metabolization_rate)
+ continue
+ //SKYRAT EDIT ADDITION END
if(C && R)
if(C.reagent_check(R) != TRUE)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index bb1c0ce5eb2..cba934e0eaa 100755
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -22,7 +22,7 @@
H.adjust_nutrition(nutriment_factor)
if(length(reagent_removal_skip_list))
return
- holder.remove_reagent(type, metabolization_rate)
+ M.remove_reagent(type, metabolization_rate) //SKYRAT EDIT CHANGE - CUSTOMIZATION (holder -> M)
/datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index 0f72fa0c2de..6c9c53403fe 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -500,6 +500,12 @@
update_disabled()
if(updating_health)
owner.updatehealth()
+ //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
+ //Consider moving this to a new species proc "spec_heal" maybe?
+ if(owner.stat == DEAD && owner?.dna?.species && (REVIVES_BY_HEALING in owner.dna.species.species_traits))
+ if(owner.health > 50 && !owner.hellbound)
+ owner.revive(FALSE)
+ //SKYRAT EDIT ADDITION END
cremation_progress = min(0, cremation_progress - ((brute_dam + burn_dam)*(100/max_damage)))
return update_bodypart_damage_state()
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 41c7aafdf7e..b32aa35b7d5 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -460,6 +460,10 @@
L.brutestate = 0
L.burnstate = 0
+ //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
+ if(dna?.species && (ROBOTIC_LIMBS in dna.species.species_traits))
+ L.change_bodypart_status(BODYPART_ROBOTIC)
+ //SKYRAT EDIT ADDITION END
if(!L.attach_limb(src, 1))
qdel(L)
return FALSE
diff --git a/modular_skyrat/master_files/icons/obj/drinks.dmi b/modular_skyrat/master_files/icons/obj/drinks.dmi
new file mode 100644
index 00000000000..55d0c560d44
Binary files /dev/null and b/modular_skyrat/master_files/icons/obj/drinks.dmi differ
diff --git a/modular_skyrat/modules/customization/icons/obj/surgery.dmi b/modular_skyrat/modules/customization/icons/obj/surgery.dmi
new file mode 100644
index 00000000000..54f1b379745
Binary files /dev/null and b/modular_skyrat/modules/customization/icons/obj/surgery.dmi differ
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
index 66bde2e0573..80204a2869f 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm
@@ -2,9 +2,10 @@
key = "snout"
generic = "Snout"
var/use_muzzled_sprites = TRUE
+ recommended_species = list("mammal", "lizard")
/datum/sprite_accessory/snouts/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
- if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE)) || !HD || HD.status == BODYPART_ROBOTIC)
+ if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE)) || !HD)
return TRUE
return FALSE
diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/synthliz.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
index 662071face1..d08639a55c9 100644
--- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
+++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
@@ -18,7 +18,7 @@
icon_state = "synthliz_tert"
/datum/sprite_accessory/snouts/synthliz/synthliz_tertunder
- color_src = USE_ONE_COLOR
+ color_src = USE_MATRIXED_COLORS
name = "Synthetic Lizard - Snout Tertiary Under"
icon_state = "synthliz_tertunder"
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
index 293dc6c0372..253c00fa04d 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm
@@ -70,13 +70,13 @@
return
/mob/living/carbon/human/species/synthliz
- race = /datum/species/synthliz
+ race = /datum/species/robotic/synthliz
/mob/living/carbon/human/species/vox
race = /datum/species/vox
/mob/living/carbon/human/species/ipc
- race = /datum/species/ipc
+ race = /datum/species/robotic/ipc
/mob/living/carbon/human/species/mammal
race = /datum/species/mammal
@@ -122,3 +122,8 @@
underwear_visibility = UNDERWEAR_HIDE_UNDIES | UNDERWEAR_HIDE_SHIRT | UNDERWEAR_HIDE_SOCKS
update_body()
return
+
+/mob/living/carbon/human/revive(full_heal = 0, admin_revive = 0)
+ if(..())
+ if(dna && dna.species)
+ dna.species.spec_revival(src)
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defense.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defense.dm
new file mode 100644
index 00000000000..8f59049d76f
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human_defense.dm
@@ -0,0 +1,34 @@
+/mob/living/carbon/human/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_CONTENTS)
+ return
+ var/informed = FALSE
+ var/affects_leg = FALSE
+ var/stun_time = 0
+ for(var/obj/item/bodypart/L in src.bodyparts)
+ if(L.status == BODYPART_ROBOTIC)
+ if(!informed)
+ to_chat(src, "You feel a sharp pain as your robotic limbs overload.")
+ informed = TRUE
+ switch(severity)
+ if(1)
+ L.receive_damage(0,6)
+ stun_time += 40
+ if(2)
+ L.receive_damage(0,3)
+ stun_time += 20
+ if(L.body_zone == BODY_ZONE_L_LEG || L.body_zone == BODY_ZONE_R_LEG)
+ affects_leg = TRUE
+
+
+ if(L.body_zone == BODY_ZONE_L_ARM || L.body_zone == BODY_ZONE_R_ARM)
+ dropItemToGround(get_item_for_held_index(L.held_index), 1)
+
+ if(stun_time)
+ Paralyze(stun_time)
+ if(affects_leg)
+ switch(severity)
+ if(1)
+ Knockdown(100)
+ if(2)
+ Knockdown(50)
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
index 2cd008faf72..0c75e490b35 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
@@ -8,6 +8,8 @@
var/list/list/body_markings = list()
///Override of the eyes icon file, used for Vox and maybe more in the future
var/eyes_icon
+ ///How are we treated regarding processing reagents, by default we process them as if we're organic
+ var/reagent_flags = PROCESS_ORGANIC
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
@@ -353,6 +355,10 @@
fly = new
fly.Grant(C)
+ if(ROBOTIC_LIMBS in species_traits)
+ for(var/obj/item/bodypart/B in C.bodyparts)
+ B.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE)
+
C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, multiplicative_slowdown=speedmod)
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -483,3 +489,12 @@
return
T.wagging = FALSE
H.update_body()
+
+/datum/species/on_species_loss(mob/living/carbon/C, datum/species/old_species, pref_load)
+ . = ..()
+ if(ROBOTIC_LIMBS in species_traits)
+ for(var/obj/item/bodypart/B in C.bodyparts)
+ B.change_bodypart_status(BODYPART_ORGANIC, FALSE, TRUE)
+
+/datum/species/proc/spec_revival(mob/living/carbon/human/H)
+ return
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ipc.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ipc.dm
deleted file mode 100644
index 9d395b855c6..00000000000
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ipc.dm
+++ /dev/null
@@ -1,49 +0,0 @@
-/datum/species/ipc
- name = "I.P.C."
- id = "ipc"
- say_mod = "beeps"
- default_color = "00FF00"
- species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,LIPS,HAS_FLESH,HAS_BONE,HAIR,NOEYESPRITES)
- inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
- default_features = null
- mutant_bodyparts = list()
- default_mutant_bodyparts = list("ipc_antenna" = ACC_RANDOM, "ipc_screen" = ACC_RANDOM, "ipc_chassis" = ACC_RANDOM)
- changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
- limbs_icon = 'modular_skyrat/modules/customization/icons/mob/species/ipc_parts.dmi'
- hair_alpha = 210
- sexes = 0
- var/datum/action/innate/monitor_change/screen
-
-/datum/species/ipc/on_species_gain(mob/living/carbon/human/C)
- . = ..()
- if(!screen)
- screen = new
- screen.Grant(C)
- var/chassis = C.dna.mutant_bodyparts["ipc_chassis"]
- if(!chassis)
- return
- var/datum/sprite_accessory/ipc_chassis/chassis_of_choice = GLOB.sprite_accessories["ipc_chassis"][chassis[MUTANT_INDEX_NAME]]
- if(chassis_of_choice)
- limbs_id = chassis_of_choice.icon_state
- if(chassis_of_choice.color_src)
- species_traits += MUTCOLORS
- C.update_body()
-
-/datum/species/ipc/on_species_loss(mob/living/carbon/human/C)
- if(screen)
- screen.Remove(C)
- ..()
-
-/datum/action/innate/monitor_change
- name = "Screen Change"
- check_flags = AB_CHECK_CONSCIOUS
- icon_icon = 'icons/mob/actions/actions_silicon.dmi'
- button_icon_state = "drone_vision"
-
-/datum/action/innate/monitor_change/Activate()
- var/mob/living/carbon/human/H = owner
- var/new_ipc_screen = input(usr, "Choose your character's screen:", "Monitor Display") as null|anything in GLOB.sprite_accessories["ipc_screen"]
- if(!new_ipc_screen)
- return
- H.dna.species.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = new_ipc_screen
- H.update_body()
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/robotic.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/robotic.dm
new file mode 100644
index 00000000000..7c07cdec6b2
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/robotic.dm
@@ -0,0 +1,121 @@
+/datum/species/robotic
+ say_mod = "beeps"
+ default_color = "00FF00"
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
+ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH, TRAIT_TOXIMMUNE, TRAIT_NOCLONELOSS, TRAIT_GENELESS, TRAIT_STABLEHEART,TRAIT_LIMBATTACHMENT, TRAIT_NO_HUSK)
+ default_features = null
+ mutant_bodyparts = list()
+ changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
+ reagent_flags = PROCESS_SYNTHETIC
+ coldmod = 0.5
+ burnmod = 1.1
+ heatmod = 1.2
+ brutemod = 1.1
+ siemens_coeff = 1.2 //Not more because some shocks will outright crit you, which is very unfun
+ mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord)
+ mutantbrain = /obj/item/organ/brain/ipc_positron
+ mutantstomach = /obj/item/organ/stomach/robot_ipc
+ mutantears = /obj/item/organ/ears/robot_ipc
+ mutanttongue = /obj/item/organ/tongue/robot_ipc
+ mutanteyes = /obj/item/organ/eyes/robot_ipc
+ mutantlungs = /obj/item/organ/lungs/robot_ipc
+ mutantheart = /obj/item/organ/heart/robot_ipc
+ mutantliver = /obj/item/organ/liver/robot_ipc
+ exotic_blood = /datum/reagent/fuel/oil
+
+/datum/species/robotic/spec_life(mob/living/carbon/human/H)
+ if(H.stat == SOFT_CRIT || H.stat == HARD_CRIT)
+ H.adjustFireLoss(1) //Still deal some damage in case a cold environment would be preventing us from the sweet release to robot heaven
+ H.adjust_bodytemperature(13) //We're overheating!!
+ if(prob(10))
+ to_chat(H, "Alert: Critical damage taken! Cooling systems failing!")
+ do_sparks(3, TRUE, H)
+
+/datum/species/robotic/spec_revival(mob/living/carbon/human/H)
+ playsound(H.loc, 'sound/machines/chime.ogg', 50, 1, -1)
+ H.visible_message("[H]'s monitor lights up.", "All systems nominal. You're back online!")
+
+/datum/species/robotic/on_species_gain(mob/living/carbon/human/C)
+ . = ..()
+ var/obj/item/organ/appendix/appendix = C.getorganslot(ORGAN_SLOT_APPENDIX)
+ if(appendix)
+ appendix.Remove(C)
+ qdel(appendix)
+
+/datum/species/robotic/ipc
+ name = "I.P.C."
+ id = "ipc"
+ species_traits = list(ROBOTIC_DNA_ORGANS,MUTCOLORS_PARTSONLY,EYECOLOR,LIPS,HAIR,NOEYESPRITES,ROBOTIC_LIMBS,NOTRANSSTING,REVIVES_BY_HEALING)
+ mutant_bodyparts = list()
+ default_mutant_bodyparts = list("ipc_antenna" = ACC_RANDOM, "ipc_screen" = ACC_RANDOM, "ipc_chassis" = ACC_RANDOM)
+ changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
+ limbs_icon = 'modular_skyrat/modules/customization/icons/mob/species/ipc_parts.dmi'
+ hair_alpha = 210
+ sexes = 0
+ var/datum/action/innate/monitor_change/screen
+ var/saved_screen = "Blank"
+
+/datum/species/robotic/ipc/spec_revival(mob/living/carbon/human/H)
+ . = ..()
+ H.dna.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = "BSOD"
+ sleep(3 SECONDS)
+ H.dna.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = saved_screen
+
+/datum/species/robotic/ipc/spec_death(gibbed, mob/living/carbon/human/H)
+ . = ..()
+ saved_screen = H.dna.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME]
+ H.dna.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = "BSOD"
+ sleep(3 SECONDS)
+ H.dna.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = "Blank"
+
+/datum/species/robotic/ipc/on_species_gain(mob/living/carbon/human/C)
+ . = ..()
+ if(!screen)
+ screen = new
+ screen.Grant(C)
+ var/chassis = C.dna.mutant_bodyparts["ipc_chassis"]
+ if(!chassis)
+ return
+ var/datum/sprite_accessory/ipc_chassis/chassis_of_choice = GLOB.sprite_accessories["ipc_chassis"][chassis[MUTANT_INDEX_NAME]]
+ if(chassis_of_choice)
+ limbs_id = chassis_of_choice.icon_state
+ if(chassis_of_choice.color_src)
+ species_traits += MUTCOLORS
+ C.update_body()
+
+/datum/species/robotic/ipc/on_species_loss(mob/living/carbon/human/C)
+ . = ..()
+ if(screen)
+ screen.Remove(C)
+ ..()
+
+/datum/action/innate/monitor_change
+ name = "Screen Change"
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'icons/mob/actions/actions_silicon.dmi'
+ button_icon_state = "drone_vision"
+
+/datum/action/innate/monitor_change/Activate()
+ var/mob/living/carbon/human/H = owner
+ var/new_ipc_screen = input(usr, "Choose your character's screen:", "Monitor Display") as null|anything in GLOB.sprite_accessories["ipc_screen"]
+ if(!new_ipc_screen)
+ return
+ H.dna.species.mutant_bodyparts["ipc_screen"][MUTANT_INDEX_NAME] = new_ipc_screen
+ H.update_body()
+
+/datum/species/robotic/synthliz
+ name = "Synthetic Lizardperson"
+ id = "synthliz"
+ species_traits = list(ROBOTIC_DNA_ORGANS,MUTCOLORS,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,NOTRANSSTING,REVIVES_BY_HEALING)
+ mutant_bodyparts = list()
+ default_mutant_bodyparts = list("ipc_antenna" = ACC_RANDOM, "tail" = ACC_RANDOM, "snout" = ACC_RANDOM, "legs" = "Digitigrade Legs", "taur" = "None")
+ changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
+ limbs_icon = 'modular_skyrat/modules/customization/icons/mob/species/synthliz_parts_greyscale.dmi'
+
+/datum/species/robotic/synthliz/get_random_body_markings(list/passed_features)
+ var/name = pick("Synth Pecs Lights", "Synth Scutes", "Synth Pecs")
+ var/datum/body_marking_set/BMS = GLOB.body_marking_sets[name]
+ var/list/markings = list()
+ if(BMS)
+ markings = assemble_body_markings_from_set(BMS, passed_features, src)
+ return markings
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/synthliz.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/synthliz.dm
deleted file mode 100644
index 5b60fdcf1f2..00000000000
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/synthliz.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/datum/species/synthliz
- name = "Synthetic Lizardperson"
- id = "synthliz"
- say_mod = "beeps"
- default_color = "00FF00"
- species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAS_FLESH,HAS_BONE,HAIR)
- inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
- default_features = null
- mutant_bodyparts = list()
- default_mutant_bodyparts = list("ipc_antenna" = ACC_RANDOM, "tail" = ACC_RANDOM, "snout" = ACC_RANDOM, "legs" = "Digitigrade Legs", "taur" = "None")
- changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
- limbs_icon = 'modular_skyrat/modules/customization/icons/mob/species/synthliz_parts_greyscale.dmi'
-
-/datum/species/synthliz/get_random_body_markings(list/passed_features)
- var/name = pick("Synth Pecs Lights", "Synth Scutes", "Synth Pecs")
- var/datum/body_marking_set/BMS = GLOB.body_marking_sets[name]
- var/list/markings = list()
- if(BMS)
- markings = assemble_body_markings_from_set(BMS, passed_features, src)
- return markings
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/status_procs.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/status_procs.dm
new file mode 100644
index 00000000000..2c16fea7fba
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/status_procs.dm
@@ -0,0 +1,3 @@
+/mob/living/carbon/human/become_husk(source)
+ if(!HAS_TRAIT(src, TRAIT_NO_HUSK))
+ . = ..()
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents.dm
new file mode 100644
index 00000000000..61acf8ede7a
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents.dm
@@ -0,0 +1,5 @@
+/datum/reagent
+ ///What can process this? REAGENT_ORGANIC, REAGENT_SYNTHETIC, or REAGENT_ORGANIC | REAGENT_SYNTHETIC?. We'll assume by default that it affects organics.
+ var/process_flags = REAGENT_ORGANIC
+ ///The icon override used for glass sprites, needed for modularity
+ var/glass_icon
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm
new file mode 100644
index 00000000000..01ebe81c198
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -0,0 +1,93 @@
+/datum/reagent/consumable/ethanol/whiskey
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC //let's not force the detective to change his alcohol brand
+
+// ROBOT ALCOHOL PAST THIS POINT
+// WOOO!
+
+/datum/reagent/consumable/ethanol/synthanol
+ name = "Synthanol"
+ description = "A runny liquid with conductive capacities. Its effects on synthetics are similar to those of alcohol on organics."
+ color = "#1BB1FF"
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+ boozepwr = 50
+ quality = DRINK_NICE
+ glass_icon = 'modular_skyrat/master_files/icons/obj/drinks.dmi'
+ glass_icon_state = "synthanolglass"
+ glass_name = "Glass of Synthanol"
+ glass_desc = "The equivalent of alcohol for synthetic crewmembers. They'd find it awful if they had tastebuds too."
+ taste_description = "motor oil"
+
+/datum/reagent/consumable/ethanol/synthanol/on_mob_life(mob/living/carbon/C)
+ if(!(C.mob_biotypes & MOB_ROBOTIC))
+ C.reagents.remove_reagent(type, 3.6) //gets removed from organics very fast
+ if(prob(25))
+ C.reagents.remove_reagent(type, 15)
+ C.vomit(5, FALSE, FALSE)
+ return ..()
+
+/datum/reagent/consumable/ethanol/synthanol/expose_mob(mob/living/carbon/C, method=TOUCH, volume)
+ . = ..()
+ if(C.mob_biotypes & MOB_ROBOTIC)
+ return
+ if(method == INGEST)
+ to_chat(C, pick("That was awful!", "That was disgusting!"))
+
+/datum/reagent/consumable/ethanol/synthanol/robottears
+ name = "Robot Tears"
+ description = "An oily substance that an IPC could technically consider a 'drink'."
+ color = "#363636"
+ boozepwr = 25
+ glass_icon_state = "robottearsglass"
+ glass_name = "Glass of Robot Tears"
+ glass_desc = "No robots were hurt in the making of this drink."
+ taste_description = "existential angst"
+
+/datum/reagent/consumable/ethanol/synthanol/trinary
+ name = "Trinary"
+ description = "A fruit drink meant only for synthetics, however that works."
+ color = "#ADB21f"
+ boozepwr = 20
+ glass_icon_state = "trinaryglass"
+ glass_name = "Glass of Trinary"
+ glass_desc = "Colorful drink made for synthetic crewmembers. It doesn't seem like it would taste well."
+ taste_description = "modem static"
+
+/datum/reagent/consumable/ethanol/synthanol/servo
+ name = "Servo"
+ description = "A drink containing some organic ingredients, but meant only for synthetics."
+ color = "#5B3210"
+ boozepwr = 25
+ glass_icon_state = "servoglass"
+ glass_name = "Glass of Servo"
+ glass_desc = "Chocolate - based drink made for IPCs. Not sure if anyone's actually tried out the recipe."
+ taste_description = "motor oil and cocoa"
+
+/datum/reagent/consumable/ethanol/synthanol/uplink
+ name = "Uplink"
+ description = "A potent mix of alcohol and synthanol. Will only work on synthetics."
+ color = "#E7AE04"
+ boozepwr = 15
+ glass_icon_state = "uplinkglass"
+ glass_name = "Glass of Uplink"
+ glass_desc = "An exquisite mix of the finest liquoirs and synthanol. Meant only for synthetics."
+ taste_description = "a GUI in visual basic"
+
+/datum/reagent/consumable/ethanol/synthanol/synthncoke
+ name = "Synth 'n Coke"
+ description = "The classic drink adjusted for a robot's tastes."
+ color = "#7204E7"
+ boozepwr = 25
+ glass_icon_state = "synthncokeglass"
+ glass_name = "Glass of Synth 'n Coke"
+ glass_desc = "Classic drink altered to fit the tastes of a robot, contains de-rustifying properties. Bad idea to drink if you're made of carbon."
+ taste_description = "fizzy motor oil"
+
+/datum/reagent/consumable/ethanol/synthanol/synthignon
+ name = "Synthignon"
+ description = "Someone mixed wine and alcohol for robots. Hope you're proud of yourself."
+ color = "#D004E7"
+ boozepwr = 25
+ glass_icon_state = "synthignonglass"
+ glass_name = "Glass of Synthignon"
+ glass_desc = "Someone mixed good wine and robot booze. Romantic, but atrocious."
+ taste_description = "fancy motor oil"
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/medicine_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/medicine_reagents.dm
new file mode 100644
index 00000000000..e8a567e9186
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -0,0 +1,71 @@
+/datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC //Let's not cripple synth ops
+
+/datum/reagent/medicine/lesser_syndicate_nanites
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/medicine/stimulants
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC //Syndicate developed 'accelerants' for synths?
+
+/datum/reagent/medicine/neo_jelly
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC //Should synthetic miners not be able to use pens? Up for a debate probably but for now lets leave their contents in
+
+/datum/reagent/medicine/lavaland_extract
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/medicine/leporazine
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+//REAGENTS FOR SYNTHS
+/datum/reagent/medicine/system_cleaner
+ name = "System Cleaner"
+ description = "Neutralizes harmful chemical compounds inside synthetic systems."
+ reagent_state = LIQUID
+ color = "#F1C40F"
+ taste_description = "ethanol"
+ metabolization_rate = 0.5 * REAGENTS_METABOLISM
+ process_flags = REAGENT_SYNTHETIC
+
+/datum/reagent/medicine/system_cleaner/on_mob_life(mob/living/carbon/M)
+ M.adjustToxLoss(-2*REM, 0)
+ . = 1
+ for(var/A in M.reagents.reagent_list)
+ var/datum/reagent/R = A
+ if(R != src)
+ M.reagents.remove_reagent(R.type,1)
+ ..()
+
+/datum/reagent/medicine/liquid_solder
+ name = "Liquid Solder"
+ description = "Repairs brain damage in synthetics."
+ color = "#727272"
+ taste_description = "metal"
+ process_flags = REAGENT_SYNTHETIC
+
+/datum/reagent/medicine/liquid_solder/on_mob_life(mob/living/carbon/C)
+ C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3*REM)
+ if(prob(10))
+ C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
+ ..()
+
+/datum/reagent/medicine/nanite_slurry
+ name = "Nanite Slurry"
+ description = "If used in touch-based applications, immediately repairs and refurbishes synthetic lifeforms, also does that while circulating in their system."
+ reagent_state = LIQUID
+ color = "#cccccc"
+ process_flags = REAGENT_SYNTHETIC
+
+/datum/reagent/medicine/nanite_slurry/expose_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
+ if(iscarbon(M))
+ if(!(method in list(INGEST, VAPOR, INJECT)))
+ M.adjustFireLoss(-reac_volume)
+ M.adjustBruteLoss(-reac_volume)
+ if(show_message)
+ to_chat(M, "You feel much better...")
+ ..()
+
+/datum/reagent/medicine/nanite_slurry/on_mob_life(mob/living/carbon/M)
+ M.adjustFireLoss(-0.5*REM, 0)
+ M.adjustBruteLoss(-0.5*REM, 0)
+ ..()
+ . = 1
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm
new file mode 100644
index 00000000000..83df092512d
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -0,0 +1,35 @@
+/datum/reagent/fuel
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/oil
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/stable_plasma
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/pax
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/water
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/hellwater
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/syndicateadrenals
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/stable_plasma/on_mob_life(mob/living/carbon/C)
+ if(C.mob_biotypes & MOB_ROBOTIC)
+ C.nutrition = min(C.nutrition + 5, NUTRITION_LEVEL_FULL-1)
+ ..()
+
+/datum/reagent/fuel/on_mob_life(mob/living/carbon/C)
+ if(C.mob_biotypes & MOB_ROBOTIC)
+ C.nutrition = min(C.nutrition + 5, NUTRITION_LEVEL_FULL-1)
+ ..()
+
+/datum/reagent/oil/on_mob_life(mob/living/carbon/C)
+ if(C.mob_biotypes & MOB_ROBOTIC && C.blood_volume < BLOOD_VOLUME_NORMAL)
+ C.blood_volume += 0.5
+ ..()
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
new file mode 100644
index 00000000000..9b0f3e4d256
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -0,0 +1,20 @@
+/datum/reagent/thermite
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/clf3
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/phlogiston
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/napalm
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/cryostylane
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/pyrosium
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/teslium
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/toxin_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/toxin_reagents.dm
new file mode 100644
index 00000000000..9a00b640324
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -0,0 +1,10 @@
+/datum/reagent/toxin/plasma
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/toxin/acid
+ process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
+
+/datum/reagent/plasma/on_mob_life(mob/living/carbon/C)
+ if(C.mob_biotypes & MOB_ROBOTIC)
+ C.nutrition = min(C.nutrition + 5, NUTRITION_LEVEL_FULL-1)
+ ..()
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm
new file mode 100644
index 00000000000..1a662c49e2b
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm
@@ -0,0 +1,14 @@
+/datum/chemical_reaction/system_cleaner
+ results = list(/datum/reagent/medicine/system_cleaner = 4)
+ required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/chlorine = 1, /datum/reagent/phenol = 2, /datum/reagent/potassium = 1)
+
+/datum/chemical_reaction/liquid_solder
+ results = list(/datum/reagent/medicine/liquid_solder = 3)
+ required_reagents = list(/datum/reagent/consumable/ethanol = 1, /datum/reagent/copper = 1, /datum/reagent/silver = 1)
+ required_temp = 370
+ mix_message = "The mixture becomes a metallic slurry."
+
+/datum/chemical_reaction/nanite_slurry
+ results = list(/datum/reagent/medicine/nanite_slurry = 3)
+ required_reagents = list(/datum/reagent/foaming_agent = 1, /datum/reagent/gold = 1, /datum/reagent/iron = 1)
+ mix_message = "The mixture becomes a metallic slurry."
diff --git a/modular_skyrat/modules/customization/modules/surgery/bodyparts/_bodyparts.dm b/modular_skyrat/modules/customization/modules/surgery/bodyparts/_bodyparts.dm
index 6a37be2bf39..52814c96f1d 100644
--- a/modular_skyrat/modules/customization/modules/surgery/bodyparts/_bodyparts.dm
+++ b/modular_skyrat/modules/customization/modules/surgery/bodyparts/_bodyparts.dm
@@ -33,7 +33,7 @@
if((body_zone != BODY_ZONE_HEAD && body_zone != BODY_ZONE_CHEST))
should_draw_gender = FALSE
- if(is_organic_limb())
+ if(species_id)
if(should_draw_greyscale)
limb.icon = rendered_bp_icon || 'icons/mob/human_parts_greyscale.dmi' //Skyrat change - customization
if(should_draw_gender)
diff --git a/modular_skyrat/modules/customization/modules/surgery/mechanic_steps.dm b/modular_skyrat/modules/customization/modules/surgery/mechanic_steps.dm
new file mode 100644
index 00000000000..08f5bca2a20
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/mechanic_steps.dm
@@ -0,0 +1,103 @@
+//cut wires
+/datum/surgery_step/cut_wires
+ name = "cut wires"
+ implements = list(
+ TOOL_WIRECUTTER = 100,
+ TOOL_SCALPEL = 75,
+ /obj/item/kitchen/knife = 50,
+ /obj/item = 10) // 10% success with any sharp item.
+ time = 24
+
+/datum/surgery_step/cut_wires/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to cut loose wires in [target]'s [parse_zone(target_zone)]...",
+ "[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].",
+ "[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].")
+
+/datum/surgery_step/cut_wires/tool_check(mob/user, obj/item/tool)
+ if(implement_type == /obj/item && !tool.get_sharpness())
+ return FALSE
+ return TRUE
+
+//pry off plating
+/datum/surgery_step/pry_off_plating
+ name = "pry off plating"
+ implements = list(
+ TOOL_CROWBAR = 100,
+ TOOL_HEMOSTAT = 10)
+ time = 24
+
+/datum/surgery_step/pry_off_plating/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ do_sparks(rand(5, 9), FALSE, target.loc)
+ return TRUE
+
+/datum/surgery_step/pry_off_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to pry off [target]'s [parse_zone(target_zone)] plating...",
+ "[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.",
+ "[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.")
+
+//weld plating
+/datum/surgery_step/weld_plating
+ name = "weld plating"
+ implements = list(
+ TOOL_WELDER = 100)
+ time = 24
+
+/datum/surgery_step/weld_plating/tool_check(mob/user, obj/item/tool)
+ if(implement_type == TOOL_WELDER && !tool.use_tool(user, user, 0, volume=50, amount=1))
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/weld_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to weld [target]'s [parse_zone(target_zone)] plating...",
+ "[user] begins to weld [target]'s [parse_zone(target_zone)] plating.",
+ "[user] begins to weld [target]'s [parse_zone(target_zone)] plating.")
+
+//replace wires
+/datum/surgery_step/replace_wires
+ name = "replace wires"
+ implements = list(/obj/item/stack/cable_coil = 100)
+ time = 24
+ var/cableamount = 5
+
+/datum/surgery_step/replace_wires/tool_check(mob/user, obj/item/tool)
+ var/obj/item/stack/cable_coil/coil = tool
+ if(coil.get_amount() < cableamount)
+ to_chat(user, "Not enough cable!")
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/replace_wires/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/stack/cable_coil/coil = tool
+ if(coil && !(coil.get_amount()You begin to replace [target]'s [parse_zone(target_zone)] wiring...",
+ "[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.",
+ "[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.")
+
+//add plating
+/datum/surgery_step/add_plating
+ name = "add plating"
+ implements = list(/obj/item/stack/sheet/metal = 100)
+ time = 24
+ var/metalamount = 5
+
+/datum/surgery_step/add_plating/tool_check(mob/user, obj/item/tool)
+ var/obj/item/stack/sheet/metal/plat = tool
+ if(plat.get_amount() < metalamount)
+ to_chat(user, "Not enough metal!")
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/add_plating/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/stack/sheet/metal/plat = tool
+ if(plat && !(plat.get_amount()You begin to add plating to [target]'s [parse_zone(target_zone)]...",
+ "[user] begins to add plating to [target]'s [parse_zone(target_zone)].",
+ "[user] begins to add plating to [target]'s [parse_zone(target_zone)].")
diff --git a/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm b/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm
new file mode 100644
index 00000000000..a14ec5579f1
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm
@@ -0,0 +1,213 @@
+/obj/item/organ/brain/ipc_positron
+ name = "positronic brain carcass"
+ slot = ORGAN_SLOT_BRAIN
+ zone = BODY_ZONE_CHEST
+ status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
+ desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. It has an IPC serial number engraved on the top. It is usually slotted into the chest of synthetic crewmembers."
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "posibrain-ipc"
+
+/obj/item/organ/brain/ipc_positron/Insert(mob/living/carbon/C, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(C.stat == DEAD && ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if(H?.dna?.species && (REVIVES_BY_HEALING in H.dna.species.species_traits))
+ if(H.health > 50 && !H.hellbound)
+ H.revive(FALSE)
+
+/obj/item/organ/brain/ipc_positron/emp_act(severity)
+ switch(severity)
+ if(1)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 75, 150)
+ to_chat(owner, "Alert: Posibrain heavily damaged.")
+ if(2)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25, 150)
+ to_chat(owner, "Alert: Posibrain damaged.")
+
+/obj/item/organ/stomach/robot_ipc
+ name = "IPC micro cell"
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "stomach-ipc"
+ w_class = WEIGHT_CLASS_NORMAL
+ zone = "chest"
+ slot = "stomach"
+ desc = "A specialised cell, for IPC use only. Do not swallow."
+ status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/stomach/robot_ipc/emp_act(severity)
+ . = ..()
+ if(!owner || . & EMP_PROTECT_SELF)
+ return
+ switch(severity)
+ if(1)
+ owner.nutrition = 50
+ to_chat(owner, "Alert: Detected severe battery discharge!")
+ if(2)
+ owner.nutrition = 250
+ to_chat(owner, "Alert: Minor battery discharge!")
+
+/obj/item/organ/ears/robot_ipc
+ name = "auditory sensors"
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "ears-ipc"
+ desc = "A pair of microphones intended to be installed in an IPC head, that grant the ability to hear."
+ zone = BODY_ZONE_HEAD
+ slot = ORGAN_SLOT_EARS
+ gender = PLURAL
+ status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/ears/robot_ipc/emp_act(severity)
+ . = ..()
+ if(!owner || . & EMP_PROTECT_SELF)
+ return
+ switch(severity)
+ if(1)
+ owner.Jitter(30)
+ owner.Dizzy(30)
+ owner.Knockdown(80)
+ deaf = 30
+ to_chat(owner, "Your robotic ears are ringing, uselessly.")
+ if(2)
+ owner.Jitter(15)
+ owner.Dizzy(15)
+ owner.Knockdown(40)
+ to_chat(owner, "Your robotic ears buzz.")
+
+/obj/item/organ/tongue/robot_ipc
+ name = "robotic voicebox"
+ desc = "A voice synthesizer that can interface with organic lifeforms."
+ status = ORGAN_ROBOTIC
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "tongue-ipc"
+ say_mod = "beeps"
+ modifies_speech = TRUE
+ taste_sensitivity = 25 // not as good as an organic tongue
+ maxHealth = 100 //RoboTongue!
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/tongue/robot_ipc/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT
+
+/obj/item/organ/eyes/robot_ipc
+ name = "robotic eyes"
+ icon_state = "cybernetic_eyeballs"
+ desc = "A very basic set of optical sensors with no extra vision modes or functions."
+ status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/eyes/robot_ipc/emp_act(severity)
+ . = ..()
+ if(!owner || . & EMP_PROTECT_SELF)
+ return
+ to_chat(owner, "Static obfuscates your vision!")
+ owner.flash_act(visual = 1)
+ if(severity == EMP_HEAVY)
+ owner.adjustOrganLoss(ORGAN_SLOT_EYES, 20)
+
+/obj/item/organ/lungs/robot_ipc
+ name = "heat sink"
+ desc = "A device that transfers generated heat to a fluid medium to cool it down. Required to keep your synthetics cool-headed. It's shape resembles lungs." //Purposefully left the 'fluid medium' ambigious for interpretation of the character, whether it be air or fluid cooling
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "lungs-ipc"
+ safe_nitro_min = 0
+ safe_nitro_max = 0
+ safe_co2_min = 0
+ safe_co2_max = 0
+ safe_toxins_min = 0
+ safe_toxins_max = 0
+ safe_oxygen_min = 0 //What are you doing man, dont breathe with those!
+ safe_oxygen_max = 0
+ cold_level_1_damage = 0
+ cold_level_2_damage = 0
+ cold_level_3_damage = 0
+ status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/lungs/robot_ipc/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ switch(severity)
+ if(1)
+ to_chat(owner, "Alert: Critical cooling system failure!")
+ owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT)
+ if(2)
+ owner.adjust_bodytemperature(30*TEMPERATURE_DAMAGE_COEFFICIENT)
+
+/obj/item/organ/heart/robot_ipc
+ name = "hydraulic pump engine"
+ desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs."
+ organ_flags = ORGAN_SYNTHETIC
+ status = ORGAN_ROBOTIC
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "heart-ipc"
+
+/obj/item/organ/liver/robot_ipc
+ name = "reagent processing unit"
+ desc = "An electronic device that processes the beneficial chemicals for the synthetic user."
+ organ_flags = ORGAN_SYNTHETIC
+ status = ORGAN_ROBOTIC
+ icon = 'modular_skyrat/modules/customization/icons/obj/surgery.dmi'
+ icon_state = "liver-c"
+ filterToxins = FALSE //We dont filter them, we're immune ot them
+
+/obj/item/organ/cyberimp/arm/power_cord
+ name = "power cord implant"
+ desc = "An internal power cord hooked up to a battery. Useful if you run on volts."
+ contents = newlist(/obj/item/apc_powercord)
+ zone = "l_arm"
+
+/obj/item/apc_powercord
+ name = "power cord"
+ desc = "An internal power cord hooked up to a battery. Useful if you run on electricity. Not so much otherwise."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "wire1"
+
+/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
+ return ..()
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/obj/machinery/power/apc/A = target
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/stomach/robot_ipc/cell = locate(/obj/item/organ/stomach/robot_ipc) in H.internal_organs
+ if(!cell)
+ to_chat(H, "You try to siphon energy from the [A], but your power cell is gone!")
+ return
+
+ if(A.cell && A.cell.charge > 0)
+ if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
+ to_chat(user, "You are already fully charged!")
+ return
+ else
+ powerdraw_loop(A, H)
+ return
+
+ to_chat(user, "There is no charge to draw from that APC.")
+
+/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
+ H.visible_message("[H] inserts a power connector into the [A].", "You begin to draw power from the [A].")
+ while(do_after(H, 10, target = A))
+ if(loc != H)
+ to_chat(H, "You must keep your connector out while charging!")
+ break
+ if(A.cell.charge == 0)
+ to_chat(H, "The [A] doesn't have enough charge to spare.")
+ break
+ A.charging = 1
+ if(A.cell.charge >= 500)
+ do_sparks(1, FALSE, A)
+ H.nutrition += 50
+ A.cell.charge -= 150
+ to_chat(H, "You siphon off some of the stored charge for your own use.")
+ else
+ H.nutrition += A.cell.charge/10
+ A.cell.charge = 0
+ to_chat(H, "You siphon off as much as the [A] can spare.")
+ break
+ if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
+ to_chat(H, "You are now fully charged.")
+ break
+ H.visible_message("[H] unplugs from the [A].", "You unplug from the [A].")
diff --git a/modular_skyrat/modules/customization/modules/surgery/robot_brain_surgery.dm b/modular_skyrat/modules/customization/modules/surgery/robot_brain_surgery.dm
new file mode 100644
index 00000000000..f2071374874
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/robot_brain_surgery.dm
@@ -0,0 +1,50 @@
+/datum/surgery/robot_brain_surgery
+ name = "Reset posibrain logic (Brain surgery)"
+ steps = list(
+ /datum/surgery_step/mechanic_open,
+ /datum/surgery_step/mechanic_unwrench,
+ /datum/surgery_step/pry_off_plating,
+ /datum/surgery_step/prepare_electronics,
+ /datum/surgery_step/fix_robot_brain,
+ /datum/surgery_step/mechanic_close)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_HEAD)
+ requires_bodypart_type = BODYPART_ROBOTIC
+ desc = "A surgical procedure that restores the default behavior logic and personality matrix of an IPC posibrain."
+
+/datum/surgery_step/fix_robot_brain
+ name = "fix posibrain (multitool)"
+ implements = list(TOOL_MULTITOOL = 100, TOOL_HEMOSTAT = 35, TOOL_SCREWDRIVER = 15)
+ time = 120 //long and complicated
+/datum/surgery/robot_brain_surgery/can_start(mob/user, mob/living/carbon/target, obj/item/tool)
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(!B)
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/fix_robot_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to fix [target]'s posibrain...",
+ "[user] begins to fix [target]'s posibrain.",
+ "[user] begins to perform surgery on [target]'s posibrain.")
+
+/datum/surgery_step/fix_robot_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You succeed in fixing [target]'s posibrain.",
+ "[user] successfully fixes [target]'s posibrain!",
+ "[user] completes the surgery on [target]'s posibrain.")
+ if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
+ target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
+ target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag
+ target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) //Lobotomy tier fix cause you can't clone this!
+ return TRUE
+
+/datum/surgery_step/fix_robot_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(target.getorganslot(ORGAN_SLOT_BRAIN))
+ display_results(user, target, "You screw up, causing more damage!",
+ "[user] screws up, causing damage to the circuits!",
+ "[user] completes the surgery on [target]'s posibrain.")
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60)
+ target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
+ else
+ user.visible_message("[user] suddenly notices that the posibrain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the posibrain you were working on is not there anymore.")
+ return FALSE
diff --git a/modular_skyrat/modules/customization/modules/surgery/robot_chassis_restoration.dm b/modular_skyrat/modules/customization/modules/surgery/robot_chassis_restoration.dm
new file mode 100644
index 00000000000..178a47c4544
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/robot_chassis_restoration.dm
@@ -0,0 +1,77 @@
+/datum/surgery/robot_chassis_restoration
+ name = "Full chassis restoration (Full heal + revival)"
+ steps = list(
+ /datum/surgery_step/mechanic_unwrench,
+ /datum/surgery_step/pry_off_plating/fullbody,
+ /datum/surgery_step/cut_wires/fullbody,
+ /datum/surgery_step/replace_wires/fullbody,
+ /datum/surgery_step/prepare_electronics,
+ /datum/surgery_step/add_plating/fullbody,
+ /datum/surgery_step/weld_plating/fullbody,
+ /datum/surgery_step/finalize_chassis_restoration)
+
+ target_mobtypes = list(/mob/living/carbon/human)
+ possible_locs = list(BODY_ZONE_CHEST)
+ requires_bodypart_type = BODYPART_ROBOTIC
+ desc = "A surgical procedure that rebuilds a synthetic unit from their skeleton to full integrity, recommended if they are damaged far beyond repair."
+
+/datum/surgery_step/pry_off_plating/fullbody
+ time = 120
+
+/datum/surgery_step/pry_off_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to pry off [target]'s plating...",
+ "[user] begins to pry off [target]'s plating.",
+ "[user] begins to pry off [target]'s plating.")
+
+/datum/surgery_step/cut_wires/fullbody
+ time = 120
+
+/datum/surgery_step/cut_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to cut [target]'s loose wires...",
+ "[user] begins to cut [target]'s loose wires.",
+ "[user] begins to cut [target]'s loose wires.")
+
+/datum/surgery_step/weld_plating/fullbody
+ time = 120
+
+/datum/surgery_step/weld_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to weld [target]'s plating...",
+ "[user] begins to weld [target]'s plating.",
+ "[user] begins to weld [target]'s plating.")
+
+/datum/surgery_step/replace_wires/fullbody
+ time = 72
+ cableamount = 15
+
+/datum/surgery_step/replace_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to replace [target]'s wiring...",
+ "[user] begins to replace [target]'s wiring.",
+ "[user] begins to replace [target]'s wiring.")
+
+/datum/surgery_step/add_plating/fullbody
+ time = 120
+ metalamount = 15
+
+/datum/surgery_step/add_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to add plating to [target]...",
+ "[user] begins to add plating to [target].",
+ "[user] begins to add plating to [target].")
+
+/datum/surgery_step/finalize_chassis_restoration
+ name = "finalize chassis restoration (wrench)"
+ implements = list(
+ TOOL_WRENCH = 100)
+ time = 120
+
+/datum/surgery_step/finalize_chassis_restoration/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to finalize [target]'s chassis...",
+ "[user] begins to finalize [target]'s chassis.",
+ "[user] begins to finalize [target]'s chassis.")
+
+/datum/surgery_step/finalize_chassis_restoration/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ target.cure_husk()
+ //Revival is handled by REVIVES_BY_HEALING
+ target.heal_overall_damage(1000,1000,0, BODYPART_ROBOTIC)
+ //I call this twice because for some reason health may not update and we may not get a revival, and I cant find a good clean solution to this
+ target.heal_overall_damage(1,1,0, BODYPART_ROBOTIC)
+ return TRUE
diff --git a/modular_skyrat/modules/customization/modules/surgery/robot_healing.dm b/modular_skyrat/modules/customization/modules/surgery/robot_healing.dm
new file mode 100644
index 00000000000..15cdb60e80d
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/robot_healing.dm
@@ -0,0 +1,129 @@
+//Almost copypaste of tend wounds, with some changes
+/datum/surgery/robot_healing
+ steps = list(/datum/surgery_step/mechanic_open,
+ /datum/surgery_step/pry_off_plating,
+ /datum/surgery_step/cut_wires,
+ /datum/surgery_step/robot_heal,
+ /datum/surgery_step/mechanic_close)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_CHEST)
+ replaced_by = /datum/surgery
+ requires_bodypart_type = BODYPART_ROBOTIC
+ ignore_clothes = TRUE
+ var/healing_step_type
+ var/antispam = FALSE
+
+/datum/surgery/robot_healing/New(surgery_target, surgery_location, surgery_bodypart)
+ ..()
+ if(healing_step_type)
+ steps = list(/datum/surgery_step/mechanic_open,
+ /datum/surgery_step/pry_off_plating,
+ /datum/surgery_step/cut_wires,
+ healing_step_type,
+ /datum/surgery_step/mechanic_close)
+
+/datum/surgery_step/robot_heal
+ name = "repair body (welder/cable)"
+ implements = list(TOOL_WELDER = 100, /obj/item/stack/cable_coil = 100)
+ repeatable = TRUE
+ time = 15
+ var/healsbrute = FALSE
+ var/healsburn = FALSE
+ var/brutehealing = 0
+ var/burnhealing = 0
+ var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing!
+
+/datum/surgery_step/robot_heal/tool_check(mob/user, obj/item/tool)
+ if(implement_type == TOOL_WELDER && !tool.tool_use_check(user, 1))
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/robot_heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/woundtype
+ if(implement_type == TOOL_WELDER)
+ healsbrute = TRUE
+ healsburn = FALSE
+ woundtype = "dents"
+ else
+ healsbrute = FALSE
+ healsburn = TRUE
+ woundtype = "wiring"
+
+ if(istype(surgery,/datum/surgery/robot_healing))
+ var/datum/surgery/robot_healing/the_surgery = surgery
+ if(!the_surgery.antispam)
+ display_results(user, target, "You attempt to fix some of [target]'s [woundtype].",
+ "[user] attempts to fix some of [target]'s [woundtype].",
+ "[user] attempts to fix some of [target]'s [woundtype].")
+
+/datum/surgery_step/robot_heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ if(..())
+ while((healsbrute && target.getBruteLoss() && tool.tool_use_check(user,1)) || (healsburn && target.getFireLoss() && tool))
+ if(!..())
+ break
+
+/datum/surgery_step/robot_heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/umsg = "You succeed in fixing some of [target]'s damage" //no period, add initial space to "addons"
+ var/tmsg = "[user] fixes some of [target]'s damage" //see above
+ var/urhealedamt_brute = 0
+ if(healsbrute)
+ urhealedamt_brute = brutehealing
+ tool.use_tool(target, user, 0, volume=50, amount=1)
+ var/urhealedamt_burn = 0
+ if(healsburn)
+ urhealedamt_burn = burnhealing
+ if(tool)
+ tool.use(1)
+ if(missinghpbonus)
+ if(target.stat != DEAD)
+ urhealedamt_brute += round((target.getBruteLoss()/ missinghpbonus),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ missinghpbonus),0.1)
+ else //less healing bonus for the dead since they're expected to have lots of damage to begin with (to make TW into defib not TOO simple)
+ urhealedamt_brute += round((target.getBruteLoss()/ (missinghpbonus*5)),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ (missinghpbonus*5)),0.1)
+ if(!get_location_accessible(target, target_zone))
+ urhealedamt_brute *= 0.55
+ urhealedamt_burn *= 0.55
+ umsg += " as best as you can while they have clothing on"
+ tmsg += " as best as they can while [target] has clothing on"
+ target.heal_bodypart_damage(urhealedamt_brute,urhealedamt_burn, 0, BODYPART_ROBOTIC)
+ display_results(user, target, "[umsg].",
+ "[tmsg].",
+ "[tmsg].")
+ if(istype(surgery, /datum/surgery/robot_healing))
+ var/datum/surgery/robot_healing/the_surgery = surgery
+ the_surgery.antispam = TRUE
+ return TRUE
+
+/datum/surgery_step/robot_heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You screwed up!",
+ "[user] screws up!",
+ "[user] fixes some of [target]'s damage.", TRUE)
+ var/urdamageamt_brute = 0
+ if(healsbrute)
+ urdamageamt_brute = brutehealing * 0.8
+ var/urdamageamt_burn = 0
+ if(healsburn)
+ urdamageamt_burn = burnhealing * 0.8
+ if(missinghpbonus)
+ urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1)
+ urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1)
+
+ target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn)
+ return FALSE
+
+/***************************TYPES***************************/
+/datum/surgery/robot_healing/basic
+ name = "Repair robotic limbs (basic)"
+ healing_step_type = /datum/surgery_step/robot_heal/basic
+ desc = "A surgical procedure that provides repairs and maintenance to robotic limbs. Is slightly more efficient when the patient is severely damaged."
+ replaced_by = null
+
+/***************************STEPS***************************/
+
+/datum/surgery_step/robot_heal/basic
+ name = "repair damage"
+ brutehealing = 10
+ burnhealing = 10
+ missinghpbonus = 15
diff --git a/modular_skyrat/modules/customization/modules/surgery/robot_restore_looks.dm b/modular_skyrat/modules/customization/modules/surgery/robot_restore_looks.dm
new file mode 100644
index 00000000000..6a9224ad5da
--- /dev/null
+++ b/modular_skyrat/modules/customization/modules/surgery/robot_restore_looks.dm
@@ -0,0 +1,48 @@
+/datum/surgery/robot_restore_looks
+ name = "Restore chassis looks"
+ steps = list(
+ /datum/surgery_step/weld_plating,
+ /datum/surgery_step/restore_paintjob)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_CHEST)
+ requires_bodypart_type = BODYPART_ROBOTIC
+ desc = "A procedure that welds the robotic limbs back into the patient's preferred state aswell as re-applying their paintjob."
+
+/datum/surgery_step/restore_paintjob
+ name = "spray paint"
+ implements = list(
+ /obj/item/toy/crayon/spraycan = 100)
+ time = 58
+
+/datum/surgery_step/restore_paintjob/tool_check(mob/user, obj/item/tool)
+ var/obj/item/toy/crayon/spraycan/sc = tool
+ if(sc.is_capped)
+ to_chat(user, "Take the cap off first!")
+ return FALSE
+ if(sc.charges < 10)
+ to_chat(user, "Not enough paint in the can!")
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/restore_paintjob/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/toy/crayon/spraycan/sc = tool
+ sc.use_charges(user, 10, FALSE)
+ sc.audible_message("You hear spraying.")
+ playsound(target.loc, 'sound/effects/spray.ogg', 5, 1, 5)
+ if(target?.dna?.species)
+ for(var/obj/item/bodypart/O in target.bodyparts)
+ if(O.status == BODYPART_ROBOTIC)
+ O.rendered_bp_icon = target.dna.species.limbs_icon
+ O.species_id = target.dna.species.limbs_id
+ if(O.body_zone == BODY_ZONE_L_LEG || O.body_zone == BODY_ZONE_R_LEG)
+ if(target.dna.mutant_bodyparts["legs"] && target.dna.mutant_bodyparts["legs"][MUTANT_INDEX_NAME] == "Digitigrade Legs")
+ O.use_digitigrade = FULL_DIGITIGRADE
+ O.update_limb(O,target)
+ target.update_body()
+ return TRUE
+
+/datum/surgery_step/restore_paintjob/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to spray paint on [target]...",
+ "[user] begins to spray paint on [target]'s [parse_zone(target_zone)].",
+ "[user] begins to spray paint on [target]'s [parse_zone(target_zone)].")
diff --git a/modular_skyrat/modules/customization/readme.md b/modular_skyrat/modules/customization/readme.md
index 2fd76fe4854..147f35257f7 100644
--- a/modular_skyrat/modules/customization/readme.md
+++ b/modular_skyrat/modules/customization/readme.md
@@ -20,12 +20,19 @@ Re-writes how mutant bodyparts exist and how they're handled. Adds in a per limb
./code/modules/mob/living/carbon/human/emote.dm > /datum/emote/living/carbon/human/wag/run_emote(), /datum/emote/living/carbon/human/wag/can_run_emote()
./code/modules/mob/living/carbon/human/examine.dm > /mob/living/carbon/human/examine()
./code/modules/mob/living/carbon/human/human_update_icons.dm > /mob/living/carbon/human/update_inv_w_uniform(), /mob/living/carbon/human/update_inv_glasses(), /mob/living/carbon/human/update_inv_shoes(), /mob/living/carbon/human/update_inv_wear_suit(), /obj/item/proc/build_worn_icon(), /mob/living/carbon/human/generate_icon_render_key()
- ./code/modules/mob/living/carbon/human/species.dm > /datum/species/proc/on_species_gain(), /datum/species/proc/handle_body(), /datum/species/proc/handle_mutant_bodyparts(), /datum/species/proc/can_equip(), /datum/species/proc/can_wag_tail(), /datum/species/proc/stop_wagging_tail(), /datum/species/proc/start_wagging_tail(), /datum/species/proc/is_wagging_tail()
+ ./code/modules/mob/living/carbon/human/species.dm > /datum/species/proc/on_species_gain(), /datum/species/proc/handle_body(), /datum/species/proc/handle_mutant_bodyparts(), /datum/species/proc/can_equip(), /datum/species/proc/can_wag_tail(), /datum/species/proc/stop_wagging_tail(), /datum/species/proc/start_wagging_tail(), /datum/species/proc/is_wagging_tail(), /datum/species/proc/handle_hair()
./code/modules/mob/living/carbon/human/species_types/felinid.dm > the 5 procs related to wagging tail
./code/modules/mob/living/carbon/human/species_types/lizardpeople.dm the 5 procs related to wagging tail and - /datum/species/lizard/on_species_gain()
./code/modules/surgery/bodyparts/_bodyparts.dm > /obj/item/bodypart/proc/get_limb_icon()
./code/modules/surgery/organs/ears.dm > /obj/item/organ/ears/cat/Insert(), /obj/item/organ/ears/cat/Remove()
- ./ code/modules/surgery/organs/tails.dm > /obj/item/organ/tail/cat/Insert(), /obj/item/organ/tail/cat/Remove(), /obj/item/organ/tail/lizard/Initialize(), /obj/item/organ/tail/lizard/Insert(), /obj/item/organ/tail/lizard/Remove()
+ ./code/modules/surgery/organs/tails.dm > /obj/item/organ/tail/cat/Insert(), /obj/item/organ/tail/cat/Remove(), /obj/item/organ/tail/lizard/Initialize(), /obj/item/organ/tail/lizard/Insert(), /obj/item/organ/tail/lizard/Remove()
+ ./code/modules/surgery/bodyparts/dismemberment.dm > /mob/living/carbon/regenerate_limb()
+ ./code/modules/mob/living/carbon/human/status_procs.dm > /mob/living/carbon/human/become_husk() > APPENDED
+ ./code/modules/reagents/chemistry/holder.dm > /datum/reagents/metabolize()
+ ./code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm > /obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change()
+ ./code/modules/mob/living/carbon/human/human_defense.dm > /mob/living/carbon/human/emp_act()
+ ./code/modules/mob/living/carbon/human.dm > /mob/living/carbon/human/revive() > APPENDED
+ ./code/modules/reagents/chemistry/reagents/food_reagents.dm > datum/reagent/consumable/on_mob_life()
### Defines:
@@ -40,6 +47,9 @@ Re-writes how mutant bodyparts exist and how they're handled. Adds in a per limb
./code/__DEFINES/~skyrat_defines/DNA.dm > A TON of defines
./code/__DEFINES/~skyrat_defines/obj_flags.dm > Organ flags
./code/__DEFINES/~skyrat_defines/say.dm > MAX_FLAVOR_LEN
+ ./code/__DEFINES/~skyrat_defines/traits.dm > TRAIT_NO_HUSK
+
+ .\modular_skyrat\modules\customization\modules\reagents\chemistry\reagents.dm > var/process_flags
### Master file additions
@@ -59,6 +69,8 @@ Re-writes how mutant bodyparts exist and how they're handled. Adds in a per limb
.\modular_skyrat\master_files\icons\mob\clothing\under\uniform_taur_paw.dmi
.\modular_skyrat\master_files\icons\mob\clothing\under\uniform_taur_snake.dmi
+ ./modular_skyrat/master_files/icons/obj/drinks.dmi
+
### Included files that are not contained in this module:
- N/A
diff --git a/tgstation.dme b/tgstation.dme
index e675acfe1bc..d1872a02477 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -131,11 +131,11 @@
#include "code\__DEFINES\dcs\signals.dm"
#include "code\__DEFINES\research\anomalies.dm"
#include "code\__DEFINES\~skyrat_defines\blueshield.dm"
-#include "code\__DEFINES\~skyrat_defines\signals.dm"
-#include "code\__DEFINES\~skyrat_defines\traits.dm"
#include "code\__DEFINES\~skyrat_defines\DNA.dm"
#include "code\__DEFINES\~skyrat_defines\obj_flags.dm"
#include "code\__DEFINES\~skyrat_defines\say.dm"
+#include "code\__DEFINES\~skyrat_defines\signals.dm"
+#include "code\__DEFINES\~skyrat_defines\traits.dm"
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\_string_lists.dm"
@@ -3274,9 +3274,6 @@
#include "modular_skyrat\modules\blueshield\code\modules\clothing\under\jobs\security.dm"
#include "modular_skyrat\modules\blueshield\code\modules\clothing\under\jobs\Plasmaman\security.dm"
#include "modular_skyrat\modules\blueshield\code\modules\jobs\job_types\blueshield.dm"
-#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint.dm"
-#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint_datum.dm"
-#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint_radial.dm"
#include "modular_skyrat\modules\blueshield\code\modules\projectiles\guns\energy\special.dm"
#include "modular_skyrat\modules\customization\__DEFINES\inventory.dm"
#include "modular_skyrat\modules\customization\__DEFINES\lists.dm"
@@ -3341,25 +3338,42 @@
#include "modular_skyrat\modules\customization\modules\mob\dead\new_player\sprite_accessories\xeno.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\carbon_update_icons.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\human.dm"
+#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\human_defense.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\human_defines.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\human_update_icons.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species.dm"
+#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\status_procs.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\dwarf.dm"
-#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\ipc.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\lizard.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\mammal.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\podweak.dm"
+#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\robotic.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\roundstartslime.dm"
-#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\synthliz.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\vox.dm"
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\xeno.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\alcohol_reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\medicine_reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\other_reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\pyrotechnic_reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\toxin_reagents.dm"
+#include "modular_skyrat\modules\customization\modules\reagents\chemistry\recipes\medicine.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\mechanic_steps.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\robot_brain_surgery.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\robot_chassis_restoration.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\robot_healing.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\robot_restore_looks.dm"
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\_bodyparts.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\ears.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\genitals.dm"
+#include "modular_skyrat\modules\customization\modules\surgery\organs\ipc.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\organ.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\tails.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\vox.dm"
#include "modular_skyrat\modules\customization\modules\surgery\organs\wings.dm"
+#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint.dm"
+#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint_datum.dm"
+#include "modular_skyrat\modules\gunpoint\code\datum\gunpoint\gunpoint_radial.dm"
#include "modular_skyrat\modules\horrorform\code\modules\antagonists\changeling\powers\horror_form.dm"
#include "modular_skyrat\modules\horrorform\code\modules\mob\hostile\true_changeling.dm"
#include "modular_skyrat\modules\icspawning\code\_onclick\observer.dm"