[SEMI-MODULAR] CUSTOMIZATION - Makes robot people behave in a robotic way (#847)

* Robits!

* stuffs

* Pfixes

* bugfixes

* smol balance

* fixxx

* hello

* Update alcohol_reagents.dm

* WHAT DOES IT WANT OF ME

* oh right those too

* Update alcohol_reagents.dm

* Update alcohol_reagents.dm

* grrr
This commit is contained in:
Azarak
2020-09-18 01:44:25 +02:00
committed by GitHub
parent f93b362e6c
commit 3401d3bc56
36 changed files with 1146 additions and 92 deletions
+17 -7
View File
@@ -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
+2
View File
@@ -1 +1,3 @@
// Defines for some extra traits
#define TRAIT_NO_HUSK "no_husk"
#define TRAIT_NORUNNING "norunning" // You walk!
@@ -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")
@@ -465,6 +465,8 @@
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
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()
@@ -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.
+23
View File
@@ -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)
@@ -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)
. = ..()
@@ -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()
@@ -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
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

@@ -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
@@ -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"
@@ -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)
@@ -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, "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>")
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)
@@ -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
@@ -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()
@@ -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, "<span class='warning'>Alert: Critical damage taken! Cooling systems failing!</span>")
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("<span class='notice'>[H]'s monitor lights up.</span>", "<span class='notice'>All systems nominal. You're back online!</span>")
/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
@@ -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
@@ -0,0 +1,3 @@
/mob/living/carbon/human/become_husk(source)
if(!HAS_TRAIT(src, TRAIT_NO_HUSK))
. = ..()
@@ -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
@@ -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("<span class = 'danger'>That was awful!</span>", "<span class = 'danger'>That was disgusting!</span>"))
/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"
@@ -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, "<span class='notice'>You feel much better...</span>")
..()
/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
@@ -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
..()
@@ -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
@@ -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)
..()
@@ -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."
@@ -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)
@@ -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, "<span class='notice'>You begin to cut loose wires in [target]'s [parse_zone(target_zone)]...</span>",
"[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, "<span class='notice'>You begin to pry off [target]'s [parse_zone(target_zone)] plating...</span>",
"[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, "<span class='notice'>You begin to weld [target]'s [parse_zone(target_zone)] plating...</span>",
"[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, "<span class='warning'>Not enough cable!</span>")
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()<cableamount)) //failproof
coil.use(cableamount)
return TRUE
/datum/surgery_step/replace_wires/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You begin to replace [target]'s [parse_zone(target_zone)] wiring...</span>",
"[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, "<span class='warning'>Not enough metal!</span>")
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()<metalamount)) //failproof
plat.use(metalamount)
return TRUE
/datum/surgery_step/add_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You begin to add plating to [target]'s [parse_zone(target_zone)]...</span>",
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].",
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].")
@@ -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, "<span class='warning'>Alert: Posibrain heavily damaged.</span>")
if(2)
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25, 150)
to_chat(owner, "<span class='warning'>Alert: Posibrain damaged.</span>")
/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, "<span class='warning'>Alert: Detected severe battery discharge!</span>")
if(2)
owner.nutrition = 250
to_chat(owner, "<span class='warning'>Alert: Minor battery discharge!</span>")
/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, "<span class='warning'>Your robotic ears are ringing, uselessly.</span>")
if(2)
owner.Jitter(15)
owner.Dizzy(15)
owner.Knockdown(40)
to_chat(owner, "<span class='warning'>Your robotic ears buzz.</span>")
/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, "<span class='warning'>Static obfuscates your vision!</span>")
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, "<span class='warning'>Alert: Critical cooling system failure!</span>")
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, "<span class='warning'>You try to siphon energy from the [A], but your power cell is gone!</span>")
return
if(A.cell && A.cell.charge > 0)
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
to_chat(user, "<span class='warning'>You are already fully charged!</span>")
return
else
powerdraw_loop(A, H)
return
to_chat(user, "<span class='warning'>There is no charge to draw from that APC.</span>")
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
H.visible_message("<span class='notice'>[H] inserts a power connector into the [A].</span>", "<span class='notice'>You begin to draw power from the [A].</span>")
while(do_after(H, 10, target = A))
if(loc != H)
to_chat(H, "<span class='warning'>You must keep your connector out while charging!</span>")
break
if(A.cell.charge == 0)
to_chat(H, "<span class='warning'>The [A] doesn't have enough charge to spare.</span>")
break
A.charging = 1
if(A.cell.charge >= 500)
do_sparks(1, FALSE, A)
H.nutrition += 50
A.cell.charge -= 150
to_chat(H, "<span class='notice'>You siphon off some of the stored charge for your own use.</span>")
else
H.nutrition += A.cell.charge/10
A.cell.charge = 0
to_chat(H, "<span class='notice'>You siphon off as much as the [A] can spare.</span>")
break
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
to_chat(H, "<span class='notice'>You are now fully charged.</span>")
break
H.visible_message("<span class='notice'>[H] unplugs from the [A].</span>", "<span class='notice'>You unplug from the [A].</span>")
@@ -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, "<span class='notice'>You begin to fix [target]'s posibrain...</span>",
"[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, "<span class='notice'>You succeed in fixing [target]'s posibrain.</span>",
"[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, "<span class='warning'>You screw up, causing more damage!</span>",
"<span class='warning'>[user] screws up, causing damage to the circuits!</span>",
"[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("<span class='warning'>[user] suddenly notices that the posibrain [user.p_they()] [user.p_were()] working on is not there anymore.", "<span class='warning'>You suddenly notice that the posibrain you were working on is not there anymore.</span>")
return FALSE
@@ -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, "<span class='notice'>You begin to pry off [target]'s plating...</span>",
"[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, "<span class='notice'>You begin to cut [target]'s loose wires...</span>",
"[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, "<span class='notice'>You begin to weld [target]'s plating...</span>",
"[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, "<span class='notice'>You begin to replace [target]'s wiring...</span>",
"[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, "<span class='notice'>You begin to add plating to [target]...</span>",
"[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, "<span class='notice'>You begin to finalize [target]'s chassis...</span>",
"[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
@@ -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, "<span class='notice'>You attempt to fix some of [target]'s [woundtype].</span>",
"<span class='notice'>[user] attempts to fix some of [target]'s [woundtype].</span>",
"<span class='notice'>[user] attempts to fix some of [target]'s [woundtype].</span>")
/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, "<span class='notice'>[umsg].</span>",
"[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, "<span class='warning'>You screwed up!</span>",
"<span class='warning'>[user] screws up!</span>",
"<span class='notice'>[user] fixes some of [target]'s damage.</span>", 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
@@ -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, "<span class='warning'>Take the cap off first!</span>")
return FALSE
if(sc.charges < 10)
to_chat(user, "<span class='warning'>Not enough paint in the can!</span>")
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("<span class='notice'>You hear spraying.</span>")
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, "<span class='notice'>You begin to spray paint on [target]...</span>",
"[user] begins to spray paint on [target]'s [parse_zone(target_zone)].",
"[user] begins to spray paint on [target]'s [parse_zone(target_zone)].")
+14 -2
View File
@@ -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
+21 -7
View File
@@ -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"