diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index 81e6e4e6245b..9771c0342e11 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -4847,10 +4847,13 @@ /area/ruin/space/ancientstation/beta/medbay) "ui" = ( /obj/effect/decal/cleanable/shreds, -/obj/structure/alien/weeds, /obj/structure/closet/crate/secure/science{ req_access = list("away_science") }, +/obj/item/encryptionkey/headset_uncommon, +/obj/item/encryptionkey/headset_uncommon, +/obj/item/encryptionkey/headset_uncommon, +/obj/structure/alien/weeds, /obj/item/transfer_valve, /obj/item/raw_anomaly_core/bluespace, /obj/item/raw_anomaly_core/random, @@ -8624,13 +8627,13 @@ /turf/open/floor/iron/solarpanel/airless, /area/ruin/space/solars/ancientstation/charlie/solars) "Uh" = ( -/obj/machinery/power/supermatter_crystal/shard, /obj/structure/closet/crate/engineering{ name = "supermatter shard crate"; secure = 1; locked = 1; icon_state = "engi_secure_crate" }, +/obj/machinery/power/supermatter_crystal/shard/oldstation, /turf/open/floor/iron/white/textured, /area/ruin/space/ancientstation/delta/proto) "Uj" = ( diff --git a/_maps/map_files/Theseus/Theseus.dmm b/_maps/map_files/Theseus/Theseus.dmm index a8b4e408725a..dad22ba8ccd3 100644 --- a/_maps/map_files/Theseus/Theseus.dmm +++ b/_maps/map_files/Theseus/Theseus.dmm @@ -4443,6 +4443,15 @@ }, /turf/open/floor/iron/dark, /area/station/security/range) +"bqW" = ( +/obj/effect/turf_decal/tile/neutral/full, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/closet/emcloset, +/turf/open/floor/iron, +/area/station/security/processing) "brm" = ( /obj/machinery/chem_master/condimaster{ name = "CondiMaster Neo" @@ -9450,7 +9459,6 @@ /obj/machinery/door/airlock/external{ name = "Gulag Shuttle Airlock" }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, /turf/open/floor/plating, /area/station/security/processing) "cQj" = ( @@ -19743,10 +19751,6 @@ /turf/open/floor/iron, /area/station/construction) "fVH" = ( -/obj/machinery/computer/prisoner/gulag_teleporter_computer{ - dir = 8 - }, -/obj/effect/turf_decal/bot, /obj/effect/turf_decal/trimline/red/filled/line{ dir = 4 }, @@ -19756,6 +19760,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/gulag_teleporter, +/obj/effect/turf_decal/bot, +/obj/machinery/light/directional/east, /turf/open/floor/iron, /area/station/security/processing) "fVQ" = ( @@ -21898,21 +21905,16 @@ /turf/open/floor/iron/dark, /area/station/security/warden) "gFe" = ( -/obj/machinery/gulag_teleporter, -/obj/effect/turf_decal/bot, -/obj/machinery/gulag_item_reclaimer{ - pixel_x = 31 - }, -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral/half{ dir = 8 }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/light/directional/east, +/obj/effect/turf_decal/trimline/red/filled/corner, +/obj/effect/turf_decal/trimline/red/filled/corner{ + dir = 4 + }, /turf/open/floor/iron, /area/station/security/processing) "gFf" = ( @@ -33984,6 +33986,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/spawner/xmastree, /turf/open/floor/iron, /area/station/hallway/primary/central) "kgT" = ( @@ -42128,13 +42131,15 @@ /turf/closed/wall, /area/station/commons/fitness/recreation/entertainment) "mxA" = ( -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/trimline/red/filled/line{ dir = 6 }, /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, +/obj/machinery/computer/prisoner/gulag_teleporter_computer{ + dir = 8 + }, +/obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/security/processing) "mxD" = ( @@ -55293,12 +55298,13 @@ /area/station/hallway/primary/central/fore) "qtB" = ( /obj/structure/table, -/obj/item/knife{ +/obj/item/knife/kitchen{ pixel_x = -1; pixel_y = 5 }, -/obj/item/knife{ - pixel_x = -10 +/obj/item/knife/kitchen{ + pixel_x = -10; + pixel_y = 0 }, /obj/item/reagent_containers/cup/rag{ pixel_y = 5; @@ -58457,6 +58463,17 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plating, /area/station/maintenance/starboard/central) +"roL" = ( +/obj/machinery/door/airlock/security, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/red/filled/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/maintenance/port/fore) "rpb" = ( /turf/open/floor/engine/plasma, /area/station/engineering/atmos) @@ -67254,7 +67271,6 @@ /turf/open/floor/carpet, /area/station/hallway/secondary/exit/departure_lounge) "tQX" = ( -/obj/item/kirbyplants/random, /obj/effect/turf_decal/stripes/line{ dir = 5 }, @@ -67263,6 +67279,10 @@ }, /obj/structure/cable, /obj/machinery/camera/directional/east, +/obj/effect/turf_decal/delivery, +/obj/machinery/gulag_item_reclaimer{ + pixel_x = 31 + }, /turf/open/floor/iron, /area/station/security/processing) "tQY" = ( @@ -77835,7 +77855,6 @@ /obj/machinery/door/airlock/external{ name = "Gulag Shuttle Airlock" }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, /obj/machinery/light/floor/has_bulb, /turf/open/floor/plating, /area/station/security/processing) @@ -109295,7 +109314,7 @@ fTB ctl fTB rtt -cze +bqW mBO gxT xhM @@ -110066,7 +110085,7 @@ ijL ijL ijL ijL -ijL +roL ijL ijL xhM diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index e8227001977e..460000a14994 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -175,7 +175,7 @@ template_access = list( ACCESS_CAPTAIN, ACCESS_CHANGE_IDS, - ACCESS_QM, + ACCESS_HOP, ) job = /datum/job/bitrunner diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index ca21aa697171..c3fb51a129c4 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -533,7 +533,6 @@ design_ids = list( "surgery_heal_brute_upgrade", "surgery_heal_burn_upgrade", - "surgery_heal_robot_upgrade", // monkestation edit: robot surgeries "surgery_filter_upgrade", // monke edit: improved blood filter surgery ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) @@ -547,7 +546,6 @@ design_ids = list( "surgery_heal_brute_upgrade_femto", "surgery_heal_burn_upgrade_femto", - "surgery_heal_robot_upgrade_femto", // monkestation edit: robot surgeries "surgery_heal_combo", "surgery_lobotomy", "surgery_wing_reconstruction", diff --git a/monkestation/code/game/objects/items/devices/radio/encryptionkey.dm b/monkestation/code/game/objects/items/devices/radio/encryptionkey.dm index 10997d861408..e87fa9c5253c 100644 --- a/monkestation/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/monkestation/code/game/objects/items/devices/radio/encryptionkey.dm @@ -8,3 +8,10 @@ /obj/item/encryptionkey/headset_uncommon name = "dusty encryption key" channels = list(RADIO_CHANNEL_UNCOMMON = 1) + +/obj/item/encryptionkey/heads/blueshield + name = "\proper the blueshield's encryption key" + icon_state = "cypherkey_centcom" + channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1) + greyscale_config = /datum/greyscale_config/encryptionkey_centcom + greyscale_colors = "#1d2657#dca01b" diff --git a/monkestation/code/modules/blueshield/clothing.dm b/monkestation/code/modules/blueshield/clothing.dm index 2a72e2317fda..25fcea522e56 100644 --- a/monkestation/code/modules/blueshield/clothing.dm +++ b/monkestation/code/modules/blueshield/clothing.dm @@ -204,7 +204,7 @@ /obj/item/radio/headset/headset_bs name = "\proper the blueshield's headset" desc = "The headset of the guy who keeps the administration alive." - icon = 'monkestation/code/modules/blueshield/icons/radio.dmi' + icon = 'monkestation/icons/obj/radio.dmi' worn_icon = 'monkestation/code/modules/blueshift/icons/mob/clothing/ears.dmi' icon_state = "bshield_headset" worn_icon_state = "bshield_headset" diff --git a/monkestation/code/modules/blueshield/devices/sensor.dm b/monkestation/code/modules/blueshield/devices/sensor.dm index 6f8a5aca717b..7dabd73dd255 100644 --- a/monkestation/code/modules/blueshield/devices/sensor.dm +++ b/monkestation/code/modules/blueshield/devices/sensor.dm @@ -1,7 +1,7 @@ /obj/item/sensor_device/blueshield name = "blueshield's handheld monitor" desc = "A unique model of handheld crew monitor that seems to have been customized for Executive Protection purposes." - icon = 'monkestation/code/modules/blueshield/icons/device.dmi' + icon = 'monkestation/icons/obj/device.dmi' icon_state = "blueshield_scanner" /obj/item/sensor_device/blueshield/attack_self(mob/user) diff --git a/monkestation/code/modules/blueshield/gun.dm b/monkestation/code/modules/blueshield/gun.dm index d4afe1d8af2d..9e3103913a26 100644 --- a/monkestation/code/modules/blueshield/gun.dm +++ b/monkestation/code/modules/blueshield/gun.dm @@ -104,7 +104,7 @@ burst_size = 4 fire_delay = 1 - icon = 'monkestation/code/modules/blueshield/icons/gun.dmi' + icon = 'monkestation/icons/obj/weapons/guns/tech9.dmi' icon_state = "tech9" fire_sound = 'monkestation/code/modules/blueshift/sounds/pistol_light.ogg' diff --git a/monkestation/code/modules/blueshield/icons/device.dmi b/monkestation/code/modules/blueshield/icons/device.dmi deleted file mode 100644 index 449e43052746..000000000000 Binary files a/monkestation/code/modules/blueshield/icons/device.dmi and /dev/null differ diff --git a/monkestation/code/modules/blueshield/icons/praetorian.dmi b/monkestation/code/modules/blueshield/icons/praetorian.dmi deleted file mode 100644 index 1632262e8b8a..000000000000 Binary files a/monkestation/code/modules/blueshield/icons/praetorian.dmi and /dev/null differ diff --git a/monkestation/code/modules/blueshield/icons/worn_praetorian.dmi b/monkestation/code/modules/blueshield/icons/worn_praetorian.dmi deleted file mode 100644 index 373986abe4de..000000000000 Binary files a/monkestation/code/modules/blueshield/icons/worn_praetorian.dmi and /dev/null differ diff --git a/monkestation/code/modules/blueshield/modsuit/suit.dm b/monkestation/code/modules/blueshield/modsuit/suit.dm index 7314f5f60f6a..7328c7f19ec5 100644 --- a/monkestation/code/modules/blueshield/modsuit/suit.dm +++ b/monkestation/code/modules/blueshield/modsuit/suit.dm @@ -1,6 +1,6 @@ /obj/item/mod/control/pre_equipped/blueshield - worn_icon = 'monkestation/code/modules/blueshield/icons/worn_praetorian.dmi' - icon = 'monkestation/code/modules/blueshield/icons/praetorian.dmi' + worn_icon = 'monkestation/icons/mob/clothing/worn_modsuit.dmi' + icon = 'monkestation/icons/obj/clothing/modsuits/modsuit.dmi' icon_state = "praetorian-control" theme = /datum/mod_theme/blueshield applied_cell = /obj/item/stock_parts/cell/high diff --git a/monkestation/code/modules/blueshield/modsuit/theme.dm b/monkestation/code/modules/blueshield/modsuit/theme.dm index ca1bd0838c52..3cf453b73e6e 100644 --- a/monkestation/code/modules/blueshield/modsuit/theme.dm +++ b/monkestation/code/modules/blueshield/modsuit/theme.dm @@ -22,8 +22,8 @@ ) skins = list( "praetorian" = list( - MOD_ICON_OVERRIDE = 'monkestation/code/modules/blueshield/icons/praetorian.dmi', - MOD_WORN_ICON_OVERRIDE = 'monkestation/code/modules/blueshield/icons/worn_praetorian.dmi', + MOD_ICON_OVERRIDE = 'monkestation/icons/obj/clothing/modsuits/modsuit.dmi', + MOD_WORN_ICON_OVERRIDE = 'monkestation/icons/mob/clothing/worn_modsuit.dmi', HELMET_FLAGS = list( UNSEALED_LAYER = null, UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL, diff --git a/monkestation/code/modules/blueshield/radio.dm b/monkestation/code/modules/blueshield/radio.dm deleted file mode 100644 index deddf9bc4eb8..000000000000 --- a/monkestation/code/modules/blueshield/radio.dm +++ /dev/null @@ -1,6 +0,0 @@ -/obj/item/encryptionkey/heads/blueshield - name = "\proper the blueshield's encryption key" - icon_state = "cypherkey_centcom" - channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1) - greyscale_config = /datum/greyscale_config/encryptionkey_centcom - greyscale_colors = "#1d2657#dca01b" diff --git a/monkestation/code/modules/jobs/departments/departments.dm b/monkestation/code/modules/jobs/departments/departments.dm new file mode 100644 index 000000000000..447e28c76174 --- /dev/null +++ b/monkestation/code/modules/jobs/departments/departments.dm @@ -0,0 +1,15 @@ +/datum/job_department/central_command + department_name = DEPARTMENT_CENTRAL_COMMAND + department_bitflags = DEPARTMENT_BITFLAG_CENTRAL_COMMAND + department_head = /datum/job/captain + department_experience_type = EXP_TYPE_CENTRAL_COMMAND + display_order = 1 + label_class = "command" + ui_color = "#86ff82" + +/datum/job_department/late + department_name = DEPARTMENT_LATE + department_bitflags = DEPARTMENT_BITFLAG_LATE + display_order = 10 + label_class = "latejoin" + ui_color = "#0b6b2b" diff --git a/monkestation/code/modules/blueshield/job.dm b/monkestation/code/modules/jobs/job_types/blueshield.dm similarity index 90% rename from monkestation/code/modules/blueshield/job.dm rename to monkestation/code/modules/jobs/job_types/blueshield.dm index 7bd45ba2b900..236225dba23a 100644 --- a/monkestation/code/modules/blueshield/job.dm +++ b/monkestation/code/modules/jobs/job_types/blueshield.dm @@ -77,12 +77,3 @@ head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield uniform = /obj/item/clothing/under/plasmaman/blueshield - -/datum/job_department/central_command - department_name = DEPARTMENT_CENTRAL_COMMAND - department_bitflags = DEPARTMENT_BITFLAG_CENTRAL_COMMAND - department_head = /datum/job/captain - department_experience_type = EXP_TYPE_CENTRAL_COMMAND - display_order = 1 - label_class = "command" - ui_color = "#86ff82" diff --git a/monkestation/code/modules/jobs/job_types/departments/departments.dm b/monkestation/code/modules/jobs/job_types/departments/departments.dm deleted file mode 100644 index 6b2e4b6a896f..000000000000 --- a/monkestation/code/modules/jobs/job_types/departments/departments.dm +++ /dev/null @@ -1,6 +0,0 @@ -/datum/job_department/late - department_name = DEPARTMENT_LATE - department_bitflags = DEPARTMENT_BITFLAG_LATE - display_order = 10 - label_class = "latejoin" - ui_color = "#0b6b2b" diff --git a/monkestation/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm b/monkestation/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm index 1083c4474101..1f723d55e9f4 100644 --- a/monkestation/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm +++ b/monkestation/code/modules/mapfluff/ruins/spaceruin_code/oldstation.dm @@ -2,3 +2,10 @@ name = "Reminder - air distrubtion." default_raw_text = "Reminder!

Blue on layer 4 is for air.
Red on layer 2 is for the scrubbers.

\ The dispenser prints our pipes with this in mind so they dont get accidentally connected. Doesn't matter if 'purple is a pretty colour', it won't connect." + +/obj/machinery/power/supermatter_crystal/shard/oldstation + name = "Worn Supermatter Shard" + desc = "This shard has lost some of its lustrous shine." + radio_key = /obj/item/encryptionkey/headset_uncommon + emergency_channel = "Uncommon" + warning_channel = "Uncommon" diff --git a/monkestation/code/modules/smithing/ipcs/species.dm b/monkestation/code/modules/mob/living/carbon/human/species_type/ipc.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/species.dm rename to monkestation/code/modules/mob/living/carbon/human/species_type/ipc.dm diff --git a/monkestation/code/modules/smithing/oozelings/species.dm b/monkestation/code/modules/mob/living/carbon/human/species_type/oozeling.dm similarity index 100% rename from monkestation/code/modules/smithing/oozelings/species.dm rename to monkestation/code/modules/mob/living/carbon/human/species_type/oozeling.dm diff --git a/monkestation/code/modules/ranching/satyr/species.dm b/monkestation/code/modules/mob/living/carbon/human/species_type/satyr.dm similarity index 100% rename from monkestation/code/modules/ranching/satyr/species.dm rename to monkestation/code/modules/mob/living/carbon/human/species_type/satyr.dm diff --git a/monkestation/code/modules/research/techweb/all_nodes.dm b/monkestation/code/modules/research/techweb/all_nodes.dm index 185a205b6e02..f01f962f74e6 100644 --- a/monkestation/code/modules/research/techweb/all_nodes.dm +++ b/monkestation/code/modules/research/techweb/all_nodes.dm @@ -350,3 +350,22 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) hidden = TRUE +/datum/techweb_node/improved_robotic_tend_wounds + id = "improved_robotic_surgery" + display_name = "Improved Robotic Repair Surgeries" + description = "As it turns out, you don't actually need to cut out entire support rods if it's just scratched!" + prereq_ids = list("engineering") + design_ids = list( + "surgery_heal_robot_upgrade", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 900) + +/datum/techweb_node/advanced_robotic_tend_wounds + id = "advanced_robotic_surgery" + display_name = "Advanced Robotic Surgeries" + description = "Did you know Hephaestus actually has a free online tutorial for synthetic trauma repairs? It's true!" + prereq_ids = list("improved_robotic_surgery") + design_ids = list( + "surgery_heal_robot_upgrade_femto", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1300) // less expensive than the organic surgery research equivalent since its JUST tend wounds diff --git a/monkestation/code/modules/smithing/ipcs/body/internal_organs.dm b/monkestation/code/modules/smithing/ipcs/body/internal_organs.dm deleted file mode 100644 index 3a8849a9b783..000000000000 --- a/monkestation/code/modules/smithing/ipcs/body/internal_organs.dm +++ /dev/null @@ -1,411 +0,0 @@ -/obj/item/organ/internal/brain/synth - name = "compact positronic brain" - slot = ORGAN_SLOT_BRAIN - zone = BODY_ZONE_HEAD - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - maxHealth = 2 * STANDARD_ORGAN_THRESHOLD - 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 = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "posibrain-ipc" - /// The last time (in ticks) a message about brain damage was sent. Don't touch. - var/last_message_time = 0 - -/obj/item/organ/internal/brain/synth/on_insert(mob/living/carbon/brain_owner) - . = ..() - - if(brain_owner.stat != DEAD || !ishuman(brain_owner)) - return - - var/mob/living/carbon/human/user_human = brain_owner - if(HAS_TRAIT(user_human, TRAIT_REVIVES_BY_HEALING) && user_human.health > SYNTH_BRAIN_WAKE_THRESHOLD) - if(!HAS_TRAIT(user_human, TRAIT_DEFIB_BLACKLISTED)) - user_human.revive(FALSE) - -/obj/item/organ/internal/brain/synth/emp_act(severity) // EMP act against the posi, keep the cap far below the organ health - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - to_chat(owner, span_warning("01001001 00100111 01101101 00100000 01100110 01110101 01100011 01101011 01100101 01100100 00101110")) - apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM, required_organtype = ORGAN_ROBOTIC) - if(EMP_LIGHT) - to_chat(owner, span_warning("Alert: Electromagnetic damage taken in central processing unit. Error Code: 401-YT")) - apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM, required_organtype = ORGAN_ROBOTIC) - -/obj/item/organ/internal/brain/synth/apply_organ_damage(damage_amount, maximumm, required_organtype) - . = ..() - - if(owner && damage > 0 && (world.time - last_message_time) > SYNTH_BRAIN_DAMAGE_MESSAGE_INTERVAL) - last_message_time = world.time - - if(damage > BRAIN_DAMAGE_SEVERE) - to_chat(owner, span_warning("Alre: re oumtnin ilir tocorr:pa ni ne:cnrrpiioruloomatt cessingode: P1_1-H")) - return - - if(damage > BRAIN_DAMAGE_MILD) - to_chat(owner, span_warning("Alert: Minor corruption in central processing unit. Error Code: 001-HP")) - -/* -/obj/item/organ/internal/brain/synth/circuit - name = "compact AI circuit" - desc = "A compact and extremely complex circuit, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. It is usually slotted into the chest of synthetic crewmembers." - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "circuit-occupied" - inhand_icon_state = "electronic" - lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' -*/ - -/obj/item/organ/internal/brain/synth/mmi - name = "compact man-machine interface" - desc = "A compact man-machine interface, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. Unfortunately, the brain seems to be permanently attached to the circuitry, and it seems relatively sensitive to it's environment. It is usually slotted into the chest of synthetic crewmembers." - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "mmi-ipc" - -/obj/item/organ/internal/ears/synth - name = "auditory sensors" - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "ears-ipc" - desc = "A pair of microphones intended to be installed in an IPC or Synthetics head, that grant the ability to hear." - zone = BODY_ZONE_HEAD - slot = ORGAN_SLOT_EARS - gender = PLURAL - maxHealth = 1 * STANDARD_ORGAN_THRESHOLD - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - -/obj/item/organ/internal/ears/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER) - owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER) - adjustEarDamage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, SYNTH_DEAF_STACKS) - to_chat(owner, span_warning("Alert: Null feedback from auditory sensors detected, seek maintenance immediately. Error Code: AS-105")) - - if(EMP_LIGHT) - owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION) - owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION) - adjustEarDamage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, SYNTH_DEAF_STACKS) - to_chat(owner, span_warning("Alert: Anomalous feedback from auditory sensors detected. Error Code: AS-50")) - -/datum/design/synth_ears - name = "Auditory Sensors" - desc = "A pair of microphones intended to be installed in an IPC or Synthetics head, that grant the ability to hear." - id = "synth_ears" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/ears/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -/obj/item/organ/internal/eyes/synth - name = "optical sensors" - icon_state = "cybernetic_eyeballs" - desc = "A very basic set of optical sensors with no extra vision modes or functions." - maxHealth = 1 * STANDARD_ORGAN_THRESHOLD - flash_protect = FLASH_PROTECTION_WELDER - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES | ORGAN_DOESNT_PROTECT_AGAINST_CONVERSION - -/obj/item/organ/internal/eyes/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - switch(severity) - if(EMP_HEAVY) - to_chat(owner, span_warning("Alert:Severe electromagnetic interference clouds your optics with static. Error Code: I-CS6")) - apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - if(EMP_LIGHT) - to_chat(owner, span_warning("Alert: Mild interference clouds your optics with static. Error Code: I-CS0")) - apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - -/datum/design/synth_eyes - name = "Optical Sensors" - desc = "A very basic set of optical sensors with no extra vision modes or functions." - id = "synth_eyes" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/eyes/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -/obj/item/organ/internal/heart/synth - name = "hydraulic pump engine" - desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move." - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "heart-ipc-on" - base_icon_state = "heart-ipc" - maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD // 1.5x due to synthcode.tm being weird - zone = BODY_ZONE_CHEST - slot = ORGAN_SLOT_HEART - var/last_message_time = 0 - -/obj/item/organ/internal/heart/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - to_chat(owner, span_warning("Alert: Main hydraulic pump control has taken severe damage, seek maintenance immediately. Error code: HP300-10.")) - apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - if(EMP_LIGHT) - to_chat(owner, span_warning("Alert: Main hydraulic pump control has taken light damage, seek maintenance immediately. Error code: HP300-05.")) - apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - -/datum/design/synth_heart - name = "Hydraulic Pump Engine" - desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move." - id = "synth_heart" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/heart/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -/obj/item/organ/internal/liver/synth - name = "reagent processing unit" - desc = "An electronic device that processes the beneficial chemicals for the synthetic user." - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "liver-ipc" - filterToxins = FALSE //We dont filter them, we're immune to them - zone = BODY_ZONE_CHEST - slot = ORGAN_SLOT_LIVER - maxHealth = 1 * STANDARD_ORGAN_THRESHOLD - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - -/obj/item/organ/internal/liver/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - to_chat(owner, span_warning("Alert: Critical! Reagent processing unit failure, seek maintenance immediately. Error Code: DR-1k")) - apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - - if(EMP_LIGHT) - to_chat(owner, span_warning("Alert: Reagent processing unit failure, seek maintenance for diagnostic. Error Code: DR-0k")) - apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - -/datum/design/synth_liver - name = "Reagent Processing Unit" - desc = "An electronic device that processes the beneficial chemicals for the synthetic user." - id = "synth_liver" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/liver/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -/obj/item/organ/internal/lungs/synth - name = "heatsink" - 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 = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "lungs-ipc" - safe_nitro_min = 0 - safe_co2_max = 0 - safe_plasma_min = 0 - safe_plasma_max = 0 - safe_oxygen_min = 0 //What are you doing man, dont breathe with those! - safe_oxygen_max = 0 - zone = BODY_ZONE_CHEST - slot = ORGAN_SLOT_LUNGS - maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - -/obj/item/organ/internal/lungs/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - to_chat(owner, span_warning("Alert: Critical cooling system failure! Seek maintenance immediately. Error Code: 5H-17")) - owner.adjust_bodytemperature(SYNTH_HEAVY_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT) - - if(EMP_LIGHT) - to_chat(owner, span_warning("Alert: Major cooling system failure!")) - owner.adjust_bodytemperature(SYNTH_LIGHT_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT) - -/datum/design/synth_heatsink - name = "Heatsink" - 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." - id = "synth_lungs" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/lungs/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -///IPCS NO LONGER ARE PURE ELECTRICAL BEINGS, any attempts to change this outside of Borbop will be denied. Thanks. -/obj/item/organ/internal/stomach/synth - name = "synthetic bio-reactor" - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "stomach-ipc" - w_class = WEIGHT_CLASS_NORMAL - zone = BODY_ZONE_CHEST - slot = ORGAN_SLOT_STOMACH - maxHealth = 1 * STANDARD_ORGAN_THRESHOLD - zone = "chest" - slot = "stomach" - desc = "A specialised mini reactor, for synthetic use only. Has a low-power mode to ensure baseline functions. Without this, synthetics are unable to stay powered." - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - -/obj/item/organ/internal/stomach/synth/emp_act(severity) - . = ..() - - if(!owner || . & EMP_PROTECT_SELF) - return - - if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. - COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - - switch(severity) - if(EMP_HEAVY) - owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_HEAVY_EMP_CHARGE_LOSS) - apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - to_chat(owner, span_warning("Alert: Severe battery discharge!")) - - if(EMP_LIGHT) - owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_LIGHT_EMP_CHARGE_LOSS) - apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) - to_chat(owner, span_warning("Alert: Minor battery discharge!")) - -/datum/design/synth_stomach - name = "Synthetic Bio-Reactor" - desc = "A specialised mini reactor, for synthetic use only. Has a low-power mode to ensure baseline functions. Without this, synthetics are unable to stay powered." - id = "synth_stomach" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/stomach/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE - -/obj/item/organ/internal/stomach/synth/Insert(mob/living/carbon/receiver, special, drop_if_replaced) - . = ..() - RegisterSignal(receiver, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(on_borg_charge)) - -/obj/item/organ/internal/stomach/synth/Remove(mob/living/carbon/stomach_owner, special) - . = ..() - UnregisterSignal(stomach_owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT) - -///Handles charging the synth from borg chargers -/obj/item/organ/internal/stomach/synth/proc/on_borg_charge(datum/source, amount) - SIGNAL_HANDLER - - if(owner.nutrition >= NUTRITION_LEVEL_ALMOST_FULL) - return - - amount /= 50 // Lowers the charging amount so it isn't instant - owner.nutrition = min((owner.nutrition + amount), NUTRITION_LEVEL_ALMOST_FULL) // Makes sure we don't make the synth too full, which would apply the overweight slowdown - -/obj/item/organ/internal/tongue/synth - name = "synthetic voicebox" - desc = "A fully-functional synthetic tongue, encased in soft silicone. Features include high-resolution vocals and taste receptors." - icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' - icon_state = "cybertongue" - say_mod = "beeps" - attack_verb_continuous = list("beeps", "boops") - attack_verb_simple = list("beep", "boop") - modifies_speech = TRUE - taste_sensitivity = 25 // not as good as an organic tongue - maxHealth = 100 //RoboTongue! - zone = BODY_ZONE_HEAD - slot = ORGAN_SLOT_TONGUE - organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES - -/obj/item/organ/internal/tongue/synth/get_scream_sound() - return 'monkestation/sound/voice/screams/silicon/scream_silicon.ogg' - -/obj/item/organ/internal/tongue/synth/get_laugh_sound() - return pick( - 'monkestation/sound/voice/laugh/silicon/laugh_siliconE1M0.ogg', - 'monkestation/sound/voice/laugh/silicon/laugh_siliconE1M1.ogg', - 'monkestation/sound/voice/laugh/silicon/laugh_siliconM2.ogg', - ) - -/obj/item/organ/internal/tongue/synth/can_speak_language(language) - return TRUE - -/obj/item/organ/internal/tongue/synth/handle_speech(datum/source, list/speech_args) - speech_args[SPEECH_SPANS] |= SPAN_ROBOT - -/datum/design/synth_tongue - name = "Synthetic Tongue" - desc = "A fully-functional synthetic tongue, encased in soft silicone. Features include high-resolution vocals and taste receptors." - id = "synth_tongue" - build_type = PROTOLATHE | AWAY_LATHE | MECHFAB - construction_time = 4 SECONDS - materials = list( - /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, - ) - build_path = /obj/item/organ/internal/tongue/synth - category = list( - RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 - ) - departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/smithing/ipcs/research.dm b/monkestation/code/modules/smithing/ipcs/research.dm deleted file mode 100644 index c75d134db45f..000000000000 --- a/monkestation/code/modules/smithing/ipcs/research.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/techweb_node/improved_robotic_tend_wounds - id = "improved_robotic_surgery" - display_name = "Improved Robotic Repair Surgeries" - description = "As it turns out, you don't actually need to cut out entire support rods if it's just scratched!" - prereq_ids = list("engineering") - design_ids = list( - "robotic_heal_surgery_upgrade" - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 900) - -/datum/techweb_node/advanced_robotic_tend_wounds - id = "advanced_robotic_surgery" - display_name = "Advanced Robotic Surgeries" - description = "Did you know Hephaestus actually has a free online tutorial for synthetic trauma repairs? It's true!" - prereq_ids = list("improved_robotic_surgery") - design_ids = list( - "robotic_heal_surgery_upgrade_2" - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1300) // less expensive than the organic surgery research equivalent since its JUST tend wounds diff --git a/monkestation/code/modules/smithing/oozelings/body/organs.dm b/monkestation/code/modules/smithing/oozelings/body/organs.dm deleted file mode 100644 index 6e33ac028af9..000000000000 --- a/monkestation/code/modules/smithing/oozelings/body/organs.dm +++ /dev/null @@ -1,420 +0,0 @@ -/obj/item/organ/internal/eyes/jelly - name = "photosensitive eyespots" - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - -/obj/item/organ/internal/eyes/roundstartslime - name = "photosensitive eyespots" - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - -/obj/item/organ/internal/ears/jelly - name = "core audiosomes" - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - -/obj/item/organ/internal/tongue/jelly - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - -/obj/item/organ/internal/tongue/jelly/get_possible_languages() - return ..() + /datum/language/slime - -/obj/item/organ/internal/lungs/slime - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - safe_oxygen_min = 4 //We don't need much oxygen to subsist. - -/obj/item/organ/internal/lungs/slime/on_life(seconds_per_tick, times_fired) - . = ..() - operated = FALSE - -/obj/item/organ/internal/liver/slime - name = "endoplasmic reticulum" - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - organ_traits = list(TRAIT_TOXINLOVER) - -/obj/item/organ/internal/liver/slime/on_life(seconds_per_tick, times_fired) - . = ..() - operated = FALSE - -/obj/item/organ/internal/stomach/slime - name = "golgi apparatus" - zone = BODY_ZONE_CHEST - organ_flags = ORGAN_UNREMOVABLE - -/obj/item/organ/internal/stomach/slime/on_life(seconds_per_tick, times_fired) - . = ..() - operated = FALSE - -/obj/item/organ/internal/brain/slime - name = "core" - desc = "The center core of a slimeperson, technically their 'extract.' Where the cytoplasm, membrane, and organelles come from; perhaps this is also a mitochondria?" - zone = BODY_ZONE_CHEST - icon = 'monkestation/code/modules/smithing/icons/oozeling.dmi' - icon_state = "slime_core" - resistance_flags = FIRE_PROOF - - var/obj/effect/death_melt_type = /obj/effect/temp_visual/wizard/out - var/core_color = COLOR_WHITE - - var/core_ejected = FALSE - var/gps_active = TRUE - - var/datum/dna/stored_dna - - var/list/stored_items = list() - - var/rebuilt = TRUE - var/coredeath = TRUE - - var/datum/action/cooldown/membrane_murmur/membrane_mur - -/obj/item/organ/internal/brain/slime/Initialize(mapload, mob/living/carbon/organ_owner, list/examine_list) - . = ..() - membrane_mur = new /datum/action/cooldown/membrane_murmur() - colorize() - transform.Scale(2, 2) - -/obj/item/organ/internal/brain/slime/Destroy(force) - QDEL_NULL(membrane_mur) - return ..() - -/obj/item/organ/internal/brain/slime/examine() - . = ..() - if(gps_active) - . += span_notice("A dim light lowly pulsates from the center of the core, indicating an outgoing signal from a tracking microchip.") - . += span_red("You could probably snuff that out.") - . += span_hypnophrase("You remember that pouring plasma on it, if it's non-embodied, would make it regrow one.") - -/obj/item/organ/internal/brain/slime/attack_self(mob/living/user) // Allows a player (presumably an antag) to deactivate the GPS signal on a slime core - if(!(gps_active)) - return - user.visible_message(span_warning("[user] begins jamming their hand into a slime core! Slime goes everywhere!"), - span_notice("You jam your hand into the core, feeling for the densest point! Slime covers your arm."), - span_notice("You hear an obscene squelching sound.") - ) - playsound(user, 'sound/surgery/organ1.ogg', 80, TRUE) - - if(!do_after(user, 30 SECONDS, src)) - user.visible_message(span_warning("[user]'s hand slips out of the core before they can cause any harm!'"), - span_warning("Your hand slips out of the goopy core before you can find it's densest point."), - span_notice("You hear a resounding plop.") - ) - return - - user.visible_message(span_warning("[user] crunches something deep in the slime core! It gradually stops glowing."), - span_notice("You find the densest point, crushing it in your palm. The blinking light in the core slowly dissapates and items start to come out."), - span_notice("You hear a wet crunching sound.")) - playsound(user, 'sound/effects/wounds/crackandbleed.ogg', 80, TRUE) - - drop_items_to_ground(get_turf(user)) - -/obj/item/organ/internal/brain/slime/Insert(mob/living/carbon/organ_owner, special = FALSE, drop_if_replaced, no_id_transfer) - . = ..() - if(!.) - return - colorize() - core_ejected = FALSE - RegisterSignal(organ_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) - -/obj/item/organ/internal/brain/slime/proc/colorize() - if(isoozeling(owner)) - var/datum/color_palette/generic_colors/located = owner.dna.color_palettes[/datum/color_palette/generic_colors] - core_color = located.return_color(MUTANT_COLOR) - add_atom_colour(core_color, FIXED_COLOUR_PRIORITY) - -/obj/item/organ/internal/brain/slime/proc/on_stat_change(mob/living/victim, new_stat, turf/loc_override) - SIGNAL_HANDLER - - if(new_stat != DEAD) - return - - addtimer(CALLBACK(src, PROC_REF(core_ejection), victim), 0) // explode them after the current proc chain ends, to avoid weirdness - -/obj/item/organ/internal/brain/slime/proc/enable_coredeath() - coredeath = TRUE - if(owner?.stat == DEAD) - addtimer(CALLBACK(src, PROC_REF(core_ejection), owner), 0) - -/////// -/// CORE EJECTION PROC -/// Makes it so that when a slime dies, their core ejects and their body is qdel'd. - -/obj/item/organ/internal/brain/slime/proc/core_ejection(mob/living/carbon/human/victim, new_stat, turf/loc_override) - if(core_ejected || !coredeath) - return - if(QDELETED(stored_dna)) - stored_dna = new - - victim.dna.copy_dna(stored_dna) - core_ejected = TRUE - victim.visible_message(span_warning("[victim]'s body completely dissolves, collapsing outwards!"), span_notice("Your body completely dissolves, collapsing outwards!"), span_notice("You hear liquid splattering.")) - var/turf/death_turf = get_turf(victim) - - for(var/atom/movable/item as anything in victim.get_equipped_items(include_pockets = TRUE)) - victim.dropItemToGround(item) - stored_items |= item - item.forceMove(src) - - if(victim.get_organ_slot(ORGAN_SLOT_BRAIN) == src) - Remove(victim) - if(death_turf) - forceMove(death_turf) - src.wash(CLEAN_WASH) - new death_melt_type(death_turf, victim.dir) - - do_steam_effects(death_turf) - playsound(victim, 'sound/effects/blobattack.ogg', 80, TRUE) - - if(gps_active) // adding the gps signal if they have activated the ability - AddComponent(/datum/component/gps, "[victim]'s Core") - - if(brainmob) - membrane_mur.Grant(brainmob) - var/datum/antagonist/changeling/target_ling = brainmob.mind?.has_antag_datum(/datum/antagonist/changeling) - - if(target_ling) - if(target_ling.oozeling_revives > 0) - target_ling.oozeling_revives-- - addtimer(CALLBACK(src, PROC_REF(rebuild_body), null, FALSE), 30 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) - - if(IS_BLOODSUCKER(brainmob)) - var/datum/antagonist/bloodsucker/target_bloodsucker = brainmob.mind.has_antag_datum(/datum/antagonist/bloodsucker) - if(target_bloodsucker.bloodsucker_blood_volume >= OOZELING_MIN_REVIVE_BLOOD_THRESHOLD) - addtimer(CALLBACK(src, PROC_REF(rebuild_body), null, FALSE), 30 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) - target_bloodsucker.bloodsucker_blood_volume -= (OOZELING_MIN_REVIVE_BLOOD_THRESHOLD * 0.5) - - rebuilt = FALSE - victim.transfer_observers_to(src) - Remove(victim) - qdel(victim) - -/obj/item/organ/internal/brain/slime/proc/do_steam_effects(turf/loc) - var/datum/effect_system/steam_spread/steam = new() - steam.set_up(10, FALSE, loc) - steam.start() - -/////// -/// CHECK FOR REPAIR SECTION -/// Makes it so that when a slime's core has plasma poured on it, it builds a new body and moves the brain into it. - -/obj/item/organ/internal/brain/slime/check_for_repair(obj/item/item, mob/user) - if(damage && item.is_drainable() && item.reagents.has_reagent(/datum/reagent/toxin/plasma)) //attempt to heal the brain - if (item.reagents.get_reagent_amount(/datum/reagent/toxin/plasma) < 100) - user.balloon_alert(user, "too little plasma!") - return FALSE - - user.visible_message( - span_notice("[user] starts to slowly pour the contents of [item] onto [src]. It seems to bubble and roil, beginning to stretch its cytoskeleton outwards..."), - span_notice("You start to slowly pour the contents of [item] onto [src]. It seems to bubble and roil, beginning to stretch its membrane outwards..."), - span_hear("You hear bubbling.") - ) - - if(!do_after(user, 30 SECONDS, src)) - to_chat(user, span_warning("You failed to pour the contents of [item] onto [src]!")) - return FALSE - - if (item.reagents.get_reagent_amount(/datum/reagent/toxin/plasma) < 100) // minor exploit but might as well patch it - user.balloon_alert(user, "too little plasma!") - return FALSE - - user.visible_message( - span_notice("[user] pours the contents of [item] onto [src], causing it to form a proper cytoplasm and outer membrane."), - span_notice("You pour the contents of [item] onto [src], causing it to form a proper cytoplasm and outer membrane."), - span_hear("You hear a splat.") - ) - - item.reagents.remove_reagent(/datum/reagent/toxin/plasma, 100) - rebuild_body(user) - return TRUE - return ..() - -/obj/item/organ/internal/brain/slime/proc/drop_items_to_ground(turf/turf) - for(var/atom/movable/item as anything in stored_items) - item.forceMove(turf) - stored_items.Cut() - -/obj/item/organ/internal/brain/slime/proc/rebuild_body(mob/user, nugget = TRUE) as /mob/living/carbon/human - RETURN_TYPE(/mob/living/carbon/human) - if(rebuilt) - return owner - set_organ_damage(-maxHealth) // heals the brain fully - - if(gps_active) // making sure the gps signal is removed if it's active on revival - gps_active = FALSE - qdel(GetComponent(/datum/component/gps)) - - //we have the plasma. we can rebuild them. - brainmob?.mind?.grab_ghost() - if(isnull(brainmob)) - user?.balloon_alert(user, "This brain is not a viable candidate for repair!") - return null - if(isnull(brainmob.stored_dna)) - user?.balloon_alert(user, "This brain does not contain any dna!") - return null - if(isnull(brainmob.client)) - user?.balloon_alert(user, "This brain does not contain a mind!") - return null - var/mob/living/carbon/human/new_body = new /mob/living/carbon/human(drop_location()) - - rebuilt = TRUE - brainmob.client?.prefs?.safe_transfer_prefs_to(new_body) - new_body.underwear = "Nude" - new_body.undershirt = "Nude" - new_body.socks = "Nude" - stored_dna.transfer_identity(new_body, transfer_SE = TRUE) - new_body.real_name = new_body.dna.real_name - new_body.name = new_body.dna.real_name - new_body.updateappearance(mutcolor_update = TRUE) - new_body.domutcheck() - new_body.forceMove(drop_location()) - if(!nugget) - new_body.set_nutrition(NUTRITION_LEVEL_FED) - new_body.blood_volume = nugget ? (BLOOD_VOLUME_SAFE + 60) : BLOOD_VOLUME_NORMAL - REMOVE_TRAIT(new_body, TRAIT_NO_TRANSFORM, REF(src)) - if(!QDELETED(brainmob)) - SSquirks.AssignQuirks(new_body, brainmob.client) - var/obj/item/organ/internal/brain/new_body_brain = new_body.get_organ_slot(ORGAN_SLOT_BRAIN) - qdel(new_body_brain) - forceMove(new_body) - Insert(new_body) - if(nugget) - for(var/obj/item/bodypart as anything in new_body.bodyparts) - if(istype(bodypart, /obj/item/bodypart/chest)) - continue - qdel(bodypart) - new_body.visible_message(span_warning("[new_body]'s torso \"forms\" from [new_body.p_their()] core, yet to form the rest.")) - to_chat(owner, span_purple("Your torso fully forms out of your core, yet to form the rest.")) - else - new_body.visible_message(span_warning("[new_body]'s body fully forms from [new_body.p_their()] core!")) - to_chat(owner, span_purple("Your body fully forms from your core!")) - - membrane_mur.Remove(brainmob) - brainmob?.mind?.transfer_to(new_body) - new_body.grab_ghost() - transfer_observers_to(new_body) - - drop_items_to_ground(new_body.drop_location()) - return new_body - - -///The rate at which slimes regenerate their jelly normally -#define JELLY_REGEN_RATE 1.5 -///The rate at which slimes regenerate their jelly when they completely run out of it and start taking damage, usually after having cannibalized all their limbs already -#define JELLY_REGEN_RATE_EMPTY 2.5 -///The blood volume at which slimes begin to start losing nutrition -- so that IV drips can work for blood deficient slimes -#define BLOOD_VOLUME_LOSE_NUTRITION 550 - - -/obj/item/organ/internal/heart/slime - name = "slime heart" - - heart_bloodtype = /datum/blood_type/slime - var/datum/action/innate/regenerate_limbs/regenerate_limbs - -/obj/item/organ/internal/heart/slime/Insert(mob/living/carbon/receiver, special, drop_if_replaced) - . = ..() - regenerate_limbs = new - regenerate_limbs.Grant(receiver) - RegisterSignal(receiver, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(slime_blood)) - -/obj/item/organ/internal/heart/slime/Remove(mob/living/carbon/heartless, special) - . = ..() - if(regenerate_limbs) - regenerate_limbs.Remove(heartless) - qdel(regenerate_limbs) - UnregisterSignal(heartless, COMSIG_HUMAN_ON_HANDLE_BLOOD) - -/obj/item/organ/internal/heart/slime/proc/slime_blood(mob/living/carbon/human/slime, seconds_per_tick, times_fired) - SIGNAL_HANDLER - - if(slime.stat == DEAD) - return NONE - - . = HANDLE_BLOOD_NO_NUTRITION_DRAIN|HANDLE_BLOOD_NO_EFFECTS - - if(slime.blood_volume <= 0) - slime.blood_volume += JELLY_REGEN_RATE_EMPTY * seconds_per_tick - slime.adjustBruteLoss(2.5 * seconds_per_tick) - to_chat(slime, span_danger("You feel empty!")) - - if(slime.blood_volume < BLOOD_VOLUME_NORMAL) - if(slime.nutrition >= NUTRITION_LEVEL_STARVING) - slime.blood_volume += JELLY_REGEN_RATE * seconds_per_tick - if(slime.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) // don't lose nutrition if we are above a certain threshold, otherwise slimes on IV drips will still lose nutrition - slime.adjust_nutrition(-1.25 * seconds_per_tick) - - if(HAS_TRAIT(slime, TRAIT_BLOOD_DEFICIENCY)) - var/datum/quirk/blooddeficiency/blooddeficiency = slime.get_quirk(/datum/quirk/blooddeficiency) - blooddeficiency?.lose_blood(slime, seconds_per_tick) - - if(slime.blood_volume < BLOOD_VOLUME_OKAY) - if(SPT_PROB(2.5, seconds_per_tick)) - to_chat(slime, span_danger("You feel drained!")) - - if(slime.blood_volume < BLOOD_VOLUME_BAD) - Cannibalize_Body(slime) - - regenerate_limbs?.build_all_button_icons(UPDATE_BUTTON_STATUS) - return . - -/obj/item/organ/internal/heart/slime/proc/Cannibalize_Body(mob/living/carbon/human/H) - var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() - var/obj/item/bodypart/consumed_limb - if(!length(limbs_to_consume)) - H.losebreath++ - return - if(H.num_legs) //Legs go before arms - limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) - consumed_limb = H.get_bodypart(pick(limbs_to_consume)) - consumed_limb.drop_limb() - to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!")) - qdel(consumed_limb) - H.blood_volume += 20 - -/datum/action/innate/regenerate_limbs - name = "Regenerate Limbs" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "slimeheal" - button_icon = 'icons/mob/actions/actions_slime.dmi' - background_icon_state = "bg_alien" - overlay_icon_state = "bg_alien_border" - -/datum/action/innate/regenerate_limbs/IsAvailable(feedback = FALSE) - . = ..() - if(!.) - return - var/mob/living/carbon/human/H = owner - var/list/limbs_to_heal = H.get_missing_limbs() - if(!length(limbs_to_heal)) - return FALSE - if(H.blood_volume >= BLOOD_VOLUME_OKAY+40) - return TRUE - -/datum/action/innate/regenerate_limbs/Activate() - var/mob/living/carbon/human/H = owner - var/list/limbs_to_heal = H.get_missing_limbs() - if(!length(limbs_to_heal)) - to_chat(H, span_notice("You feel intact enough as it is.")) - return - to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]...")) - if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY) - H.regenerate_limbs() - H.blood_volume -= 40*length(limbs_to_heal) - to_chat(H, span_notice("...and after a moment you finish reforming!")) - return - else if(H.blood_volume >= 40)//We can partially heal some limbs - while(H.blood_volume >= BLOOD_VOLUME_OKAY+40) - var/healed_limb = pick(limbs_to_heal) - H.regenerate_limb(healed_limb) - limbs_to_heal -= healed_limb - H.blood_volume -= 40 - to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!")) - return - to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!")) - -#undef JELLY_REGEN_RATE -#undef JELLY_REGEN_RATE_EMPTY -#undef BLOOD_VOLUME_LOSE_NUTRITION diff --git a/monkestation/code/modules/smithing/ipcs/body/base_bodyparts.dm b/monkestation/code/modules/surgery/bodyparts/ipc_bodyparts.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/body/base_bodyparts.dm rename to monkestation/code/modules/surgery/bodyparts/ipc_bodyparts.dm diff --git a/monkestation/code/modules/smithing/oozelings/body/bodyparts.dm b/monkestation/code/modules/surgery/bodyparts/oozeling_bodyparts.dm similarity index 100% rename from monkestation/code/modules/smithing/oozelings/body/bodyparts.dm rename to monkestation/code/modules/surgery/bodyparts/oozeling_bodyparts.dm diff --git a/monkestation/code/modules/ranching/satyr/bodyparts.dm b/monkestation/code/modules/surgery/bodyparts/satyr_bodyparts.dm similarity index 100% rename from monkestation/code/modules/ranching/satyr/bodyparts.dm rename to monkestation/code/modules/surgery/bodyparts/satyr_bodyparts.dm diff --git a/monkestation/code/modules/surgery/organs/internal/brain.dm b/monkestation/code/modules/surgery/organs/internal/brain.dm index 54595401627b..a26374a30239 100644 --- a/monkestation/code/modules/surgery/organs/internal/brain.dm +++ b/monkestation/code/modules/surgery/organs/internal/brain.dm @@ -14,3 +14,325 @@ . = ..() if(prob(5) && !robust) SEND_SOUND(owner, sound('sound/ambience/ambiruin3.ogg', volume = 25)) + +/obj/item/organ/internal/brain/slime + name = "core" + desc = "The center core of a slimeperson, technically their 'extract.' Where the cytoplasm, membrane, and organelles come from; perhaps this is also a mitochondria?" + zone = BODY_ZONE_CHEST + icon = 'monkestation/code/modules/smithing/icons/oozeling.dmi' + icon_state = "slime_core" + resistance_flags = FIRE_PROOF + + var/obj/effect/death_melt_type = /obj/effect/temp_visual/wizard/out + var/core_color = COLOR_WHITE + + var/core_ejected = FALSE + var/gps_active = TRUE + + var/datum/dna/stored_dna + + var/list/stored_items = list() + + var/rebuilt = TRUE + var/coredeath = TRUE + + var/datum/action/cooldown/membrane_murmur/membrane_mur + +/obj/item/organ/internal/brain/slime/Initialize(mapload, mob/living/carbon/organ_owner, list/examine_list) + . = ..() + membrane_mur = new /datum/action/cooldown/membrane_murmur() + colorize() + transform.Scale(2, 2) + +/obj/item/organ/internal/brain/slime/Destroy(force) + QDEL_NULL(membrane_mur) + return ..() + +/obj/item/organ/internal/brain/slime/examine() + . = ..() + if(gps_active) + . += span_notice("A dim light lowly pulsates from the center of the core, indicating an outgoing signal from a tracking microchip.") + . += span_red("You could probably snuff that out.") + . += span_hypnophrase("You remember that pouring plasma on it, if it's non-embodied, would make it regrow one.") + +/obj/item/organ/internal/brain/slime/attack_self(mob/living/user) // Allows a player (presumably an antag) to deactivate the GPS signal on a slime core + if(!(gps_active)) + return + user.visible_message(span_warning("[user] begins jamming their hand into a slime core! Slime goes everywhere!"), + span_notice("You jam your hand into the core, feeling for the densest point! Slime covers your arm."), + span_notice("You hear an obscene squelching sound.") + ) + playsound(user, 'sound/surgery/organ1.ogg', 80, TRUE) + + if(!do_after(user, 30 SECONDS, src)) + user.visible_message(span_warning("[user]'s hand slips out of the core before they can cause any harm!'"), + span_warning("Your hand slips out of the goopy core before you can find it's densest point."), + span_notice("You hear a resounding plop.") + ) + return + + user.visible_message(span_warning("[user] crunches something deep in the slime core! It gradually stops glowing."), + span_notice("You find the densest point, crushing it in your palm. The blinking light in the core slowly dissapates and items start to come out."), + span_notice("You hear a wet crunching sound.")) + playsound(user, 'sound/effects/wounds/crackandbleed.ogg', 80, TRUE) + + drop_items_to_ground(get_turf(user)) + +/obj/item/organ/internal/brain/slime/Insert(mob/living/carbon/organ_owner, special = FALSE, drop_if_replaced, no_id_transfer) + . = ..() + if(!.) + return + colorize() + core_ejected = FALSE + RegisterSignal(organ_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) + +/obj/item/organ/internal/brain/slime/proc/colorize() + if(isoozeling(owner)) + var/datum/color_palette/generic_colors/located = owner.dna.color_palettes[/datum/color_palette/generic_colors] + core_color = located.return_color(MUTANT_COLOR) + add_atom_colour(core_color, FIXED_COLOUR_PRIORITY) + +/obj/item/organ/internal/brain/slime/proc/on_stat_change(mob/living/victim, new_stat, turf/loc_override) + SIGNAL_HANDLER + + if(new_stat != DEAD) + return + + addtimer(CALLBACK(src, PROC_REF(core_ejection), victim), 0) // explode them after the current proc chain ends, to avoid weirdness + +/obj/item/organ/internal/brain/slime/proc/enable_coredeath() + coredeath = TRUE + if(owner?.stat == DEAD) + addtimer(CALLBACK(src, PROC_REF(core_ejection), owner), 0) + +/////// +/// CORE EJECTION PROC +/// Makes it so that when a slime dies, their core ejects and their body is qdel'd. + +/obj/item/organ/internal/brain/slime/proc/core_ejection(mob/living/carbon/human/victim, new_stat, turf/loc_override) + if(core_ejected || !coredeath) + return + if(QDELETED(stored_dna)) + stored_dna = new + + victim.dna.copy_dna(stored_dna) + core_ejected = TRUE + victim.visible_message(span_warning("[victim]'s body completely dissolves, collapsing outwards!"), span_notice("Your body completely dissolves, collapsing outwards!"), span_notice("You hear liquid splattering.")) + var/turf/death_turf = get_turf(victim) + + for(var/atom/movable/item as anything in victim.get_equipped_items(include_pockets = TRUE)) + victim.dropItemToGround(item) + stored_items |= item + item.forceMove(src) + + if(victim.get_organ_slot(ORGAN_SLOT_BRAIN) == src) + Remove(victim) + if(death_turf) + forceMove(death_turf) + src.wash(CLEAN_WASH) + new death_melt_type(death_turf, victim.dir) + + do_steam_effects(death_turf) + playsound(victim, 'sound/effects/blobattack.ogg', 80, TRUE) + + if(gps_active) // adding the gps signal if they have activated the ability + AddComponent(/datum/component/gps, "[victim]'s Core") + + if(brainmob) + membrane_mur.Grant(brainmob) + var/datum/antagonist/changeling/target_ling = brainmob.mind?.has_antag_datum(/datum/antagonist/changeling) + + if(target_ling) + if(target_ling.oozeling_revives > 0) + target_ling.oozeling_revives-- + addtimer(CALLBACK(src, PROC_REF(rebuild_body), null, FALSE), 30 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) + + if(IS_BLOODSUCKER(brainmob)) + var/datum/antagonist/bloodsucker/target_bloodsucker = brainmob.mind.has_antag_datum(/datum/antagonist/bloodsucker) + if(target_bloodsucker.bloodsucker_blood_volume >= OOZELING_MIN_REVIVE_BLOOD_THRESHOLD) + addtimer(CALLBACK(src, PROC_REF(rebuild_body), null, FALSE), 30 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) + target_bloodsucker.bloodsucker_blood_volume -= (OOZELING_MIN_REVIVE_BLOOD_THRESHOLD * 0.5) + + rebuilt = FALSE + victim.transfer_observers_to(src) + Remove(victim) + qdel(victim) + +/obj/item/organ/internal/brain/slime/proc/do_steam_effects(turf/loc) + var/datum/effect_system/steam_spread/steam = new() + steam.set_up(10, FALSE, loc) + steam.start() + +/////// +/// CHECK FOR REPAIR SECTION +/// Makes it so that when a slime's core has plasma poured on it, it builds a new body and moves the brain into it. + +/obj/item/organ/internal/brain/slime/check_for_repair(obj/item/item, mob/user) + if(damage && item.is_drainable() && item.reagents.has_reagent(/datum/reagent/toxin/plasma)) //attempt to heal the brain + if (item.reagents.get_reagent_amount(/datum/reagent/toxin/plasma) < 100) + user.balloon_alert(user, "too little plasma!") + return FALSE + + user.visible_message( + span_notice("[user] starts to slowly pour the contents of [item] onto [src]. It seems to bubble and roil, beginning to stretch its cytoskeleton outwards..."), + span_notice("You start to slowly pour the contents of [item] onto [src]. It seems to bubble and roil, beginning to stretch its membrane outwards..."), + span_hear("You hear bubbling.") + ) + + if(!do_after(user, 30 SECONDS, src)) + to_chat(user, span_warning("You failed to pour the contents of [item] onto [src]!")) + return FALSE + + if (item.reagents.get_reagent_amount(/datum/reagent/toxin/plasma) < 100) // minor exploit but might as well patch it + user.balloon_alert(user, "too little plasma!") + return FALSE + + user.visible_message( + span_notice("[user] pours the contents of [item] onto [src], causing it to form a proper cytoplasm and outer membrane."), + span_notice("You pour the contents of [item] onto [src], causing it to form a proper cytoplasm and outer membrane."), + span_hear("You hear a splat.") + ) + + item.reagents.remove_reagent(/datum/reagent/toxin/plasma, 100) + rebuild_body(user) + return TRUE + return ..() + +/obj/item/organ/internal/brain/slime/proc/drop_items_to_ground(turf/turf) + for(var/atom/movable/item as anything in stored_items) + item.forceMove(turf) + stored_items.Cut() + +/obj/item/organ/internal/brain/slime/proc/rebuild_body(mob/user, nugget = TRUE) as /mob/living/carbon/human + RETURN_TYPE(/mob/living/carbon/human) + if(rebuilt) + return owner + set_organ_damage(-maxHealth) // heals the brain fully + + if(gps_active) // making sure the gps signal is removed if it's active on revival + gps_active = FALSE + qdel(GetComponent(/datum/component/gps)) + + //we have the plasma. we can rebuild them. + brainmob?.mind?.grab_ghost() + if(isnull(brainmob)) + user?.balloon_alert(user, "This brain is not a viable candidate for repair!") + return null + if(isnull(brainmob.stored_dna)) + user?.balloon_alert(user, "This brain does not contain any dna!") + return null + if(isnull(brainmob.client)) + user?.balloon_alert(user, "This brain does not contain a mind!") + return null + var/mob/living/carbon/human/new_body = new /mob/living/carbon/human(drop_location()) + + rebuilt = TRUE + brainmob.client?.prefs?.safe_transfer_prefs_to(new_body) + new_body.underwear = "Nude" + new_body.undershirt = "Nude" + new_body.socks = "Nude" + stored_dna.transfer_identity(new_body, transfer_SE = TRUE) + new_body.real_name = new_body.dna.real_name + new_body.name = new_body.dna.real_name + new_body.updateappearance(mutcolor_update = TRUE) + new_body.domutcheck() + new_body.forceMove(drop_location()) + if(!nugget) + new_body.set_nutrition(NUTRITION_LEVEL_FED) + new_body.blood_volume = nugget ? (BLOOD_VOLUME_SAFE + 60) : BLOOD_VOLUME_NORMAL + REMOVE_TRAIT(new_body, TRAIT_NO_TRANSFORM, REF(src)) + if(!QDELETED(brainmob)) + SSquirks.AssignQuirks(new_body, brainmob.client) + var/obj/item/organ/internal/brain/new_body_brain = new_body.get_organ_slot(ORGAN_SLOT_BRAIN) + qdel(new_body_brain) + forceMove(new_body) + Insert(new_body) + if(nugget) + for(var/obj/item/bodypart as anything in new_body.bodyparts) + if(istype(bodypart, /obj/item/bodypart/chest)) + continue + qdel(bodypart) + new_body.visible_message(span_warning("[new_body]'s torso \"forms\" from [new_body.p_their()] core, yet to form the rest.")) + to_chat(owner, span_purple("Your torso fully forms out of your core, yet to form the rest.")) + else + new_body.visible_message(span_warning("[new_body]'s body fully forms from [new_body.p_their()] core!")) + to_chat(owner, span_purple("Your body fully forms from your core!")) + + membrane_mur.Remove(brainmob) + brainmob?.mind?.transfer_to(new_body) + new_body.grab_ghost() + transfer_observers_to(new_body) + + drop_items_to_ground(new_body.drop_location()) + return new_body + +/obj/item/organ/internal/brain/synth + name = "compact positronic brain" + slot = ORGAN_SLOT_BRAIN + zone = BODY_ZONE_HEAD + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + maxHealth = 2 * STANDARD_ORGAN_THRESHOLD + 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 = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "posibrain-ipc" + /// The last time (in ticks) a message about brain damage was sent. Don't touch. + var/last_message_time = 0 + +/obj/item/organ/internal/brain/synth/on_insert(mob/living/carbon/brain_owner) + . = ..() + + if(brain_owner.stat != DEAD || !ishuman(brain_owner)) + return + + var/mob/living/carbon/human/user_human = brain_owner + if(HAS_TRAIT(user_human, TRAIT_REVIVES_BY_HEALING) && user_human.health > SYNTH_BRAIN_WAKE_THRESHOLD) + if(!HAS_TRAIT(user_human, TRAIT_DEFIB_BLACKLISTED)) + user_human.revive(FALSE) + +/obj/item/organ/internal/brain/synth/emp_act(severity) // EMP act against the posi, keep the cap far below the organ health + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + to_chat(owner, span_warning("01001001 00100111 01101101 00100000 01100110 01110101 01100011 01101011 01100101 01100100 00101110")) + apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM, required_organtype = ORGAN_ROBOTIC) + if(EMP_LIGHT) + to_chat(owner, span_warning("Alert: Electromagnetic damage taken in central processing unit. Error Code: 401-YT")) + apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM, required_organtype = ORGAN_ROBOTIC) + +/obj/item/organ/internal/brain/synth/apply_organ_damage(damage_amount, maximumm, required_organtype) + . = ..() + + if(owner && damage > 0 && (world.time - last_message_time) > SYNTH_BRAIN_DAMAGE_MESSAGE_INTERVAL) + last_message_time = world.time + + if(damage > BRAIN_DAMAGE_SEVERE) + to_chat(owner, span_warning("Alre: re oumtnin ilir tocorr:pa ni ne:cnrrpiioruloomatt cessingode: P1_1-H")) + return + + if(damage > BRAIN_DAMAGE_MILD) + to_chat(owner, span_warning("Alert: Minor corruption in central processing unit. Error Code: 001-HP")) + +/* +/obj/item/organ/internal/brain/synth/circuit + name = "compact AI circuit" + desc = "A compact and extremely complex circuit, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. It is usually slotted into the chest of synthetic crewmembers." + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "circuit-occupied" + inhand_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' +*/ + +/obj/item/organ/internal/brain/synth/mmi + name = "compact man-machine interface" + desc = "A compact man-machine interface, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. Unfortunately, the brain seems to be permanently attached to the circuitry, and it seems relatively sensitive to it's environment. It is usually slotted into the chest of synthetic crewmembers." + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "mmi-ipc" + diff --git a/monkestation/code/modules/surgery/organs/internal/ears.dm b/monkestation/code/modules/surgery/organs/internal/ears.dm index a448af9db39c..25ff00d61ae6 100644 --- a/monkestation/code/modules/surgery/organs/internal/ears.dm +++ b/monkestation/code/modules/surgery/organs/internal/ears.dm @@ -3,3 +3,57 @@ desc = "An odd sort of microphone that looks grown, rather than built." icon = 'monkestation/icons/obj/medical/organs/organs.dmi' icon_state = "ears-clock" + +/obj/item/organ/internal/ears/jelly + name = "core audiosomes" + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + +/obj/item/organ/internal/ears/synth + name = "auditory sensors" + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "ears-ipc" + desc = "A pair of microphones intended to be installed in an IPC or Synthetics head, that grant the ability to hear." + zone = BODY_ZONE_HEAD + slot = ORGAN_SLOT_EARS + gender = PLURAL + maxHealth = 1 * STANDARD_ORGAN_THRESHOLD + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + +/obj/item/organ/internal/ears/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER) + owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER) + adjustEarDamage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, SYNTH_DEAF_STACKS) + to_chat(owner, span_warning("Alert: Null feedback from auditory sensors detected, seek maintenance immediately. Error Code: AS-105")) + + if(EMP_LIGHT) + owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION) + owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION) + adjustEarDamage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, SYNTH_DEAF_STACKS) + to_chat(owner, span_warning("Alert: Anomalous feedback from auditory sensors detected. Error Code: AS-50")) + +/datum/design/synth_ears + name = "Auditory Sensors" + desc = "A pair of microphones intended to be installed in an IPC or Synthetics head, that grant the ability to hear." + id = "synth_ears" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/ears/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/surgery/organs/internal/eyes.dm b/monkestation/code/modules/surgery/organs/internal/eyes.dm index a70dba2e3f8f..b49eff604977 100644 --- a/monkestation/code/modules/surgery/organs/internal/eyes.dm +++ b/monkestation/code/modules/surgery/organs/internal/eyes.dm @@ -50,3 +50,51 @@ name = "tundra moth eyes" eye_icon_state = "tundramotheyes" icon_state = "eyeballs-tundramoth" + +/obj/item/organ/internal/eyes/jelly + name = "photosensitive eyespots" + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + +/obj/item/organ/internal/eyes/roundstartslime + name = "photosensitive eyespots" + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + +/obj/item/organ/internal/eyes/synth + name = "optical sensors" + icon_state = "cybernetic_eyeballs" + desc = "A very basic set of optical sensors with no extra vision modes or functions." + maxHealth = 1 * STANDARD_ORGAN_THRESHOLD + flash_protect = FLASH_PROTECTION_WELDER + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES | ORGAN_DOESNT_PROTECT_AGAINST_CONVERSION + +/obj/item/organ/internal/eyes/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + switch(severity) + if(EMP_HEAVY) + to_chat(owner, span_warning("Alert:Severe electromagnetic interference clouds your optics with static. Error Code: I-CS6")) + apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + if(EMP_LIGHT) + to_chat(owner, span_warning("Alert: Mild interference clouds your optics with static. Error Code: I-CS0")) + apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + +/datum/design/synth_eyes + name = "Optical Sensors" + desc = "A very basic set of optical sensors with no extra vision modes or functions." + id = "synth_eyes" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/eyes/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/surgery/organs/internal/heart.dm b/monkestation/code/modules/surgery/organs/internal/heart.dm index ea75864d8089..02ba08878c8a 100644 --- a/monkestation/code/modules/surgery/organs/internal/heart.dm +++ b/monkestation/code/modules/surgery/organs/internal/heart.dm @@ -5,3 +5,167 @@ icon_state = "heart-clock" organ_flags = ORGAN_SYNTHETIC status = ORGAN_ROBOTIC + +///The rate at which slimes regenerate their jelly normally +#define JELLY_REGEN_RATE 1.5 +///The rate at which slimes regenerate their jelly when they completely run out of it and start taking damage, usually after having cannibalized all their limbs already +#define JELLY_REGEN_RATE_EMPTY 2.5 +///The blood volume at which slimes begin to start losing nutrition -- so that IV drips can work for blood deficient slimes +#define BLOOD_VOLUME_LOSE_NUTRITION 550 + + +/obj/item/organ/internal/heart/slime + name = "slime heart" + + heart_bloodtype = /datum/blood_type/slime + var/datum/action/innate/regenerate_limbs/regenerate_limbs + +/obj/item/organ/internal/heart/slime/Insert(mob/living/carbon/receiver, special, drop_if_replaced) + . = ..() + regenerate_limbs = new + regenerate_limbs.Grant(receiver) + RegisterSignal(receiver, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(slime_blood)) + +/obj/item/organ/internal/heart/slime/Remove(mob/living/carbon/heartless, special) + . = ..() + if(regenerate_limbs) + regenerate_limbs.Remove(heartless) + qdel(regenerate_limbs) + UnregisterSignal(heartless, COMSIG_HUMAN_ON_HANDLE_BLOOD) + +/obj/item/organ/internal/heart/slime/proc/slime_blood(mob/living/carbon/human/slime, seconds_per_tick, times_fired) + SIGNAL_HANDLER + + if(slime.stat == DEAD) + return NONE + + . = HANDLE_BLOOD_NO_NUTRITION_DRAIN|HANDLE_BLOOD_NO_EFFECTS + + if(slime.blood_volume <= 0) + slime.blood_volume += JELLY_REGEN_RATE_EMPTY * seconds_per_tick + slime.adjustBruteLoss(2.5 * seconds_per_tick) + to_chat(slime, span_danger("You feel empty!")) + + if(slime.blood_volume < BLOOD_VOLUME_NORMAL) + if(slime.nutrition >= NUTRITION_LEVEL_STARVING) + slime.blood_volume += JELLY_REGEN_RATE * seconds_per_tick + if(slime.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) // don't lose nutrition if we are above a certain threshold, otherwise slimes on IV drips will still lose nutrition + slime.adjust_nutrition(-1.25 * seconds_per_tick) + + if(HAS_TRAIT(slime, TRAIT_BLOOD_DEFICIENCY)) + var/datum/quirk/blooddeficiency/blooddeficiency = slime.get_quirk(/datum/quirk/blooddeficiency) + blooddeficiency?.lose_blood(slime, seconds_per_tick) + + if(slime.blood_volume < BLOOD_VOLUME_OKAY) + if(SPT_PROB(2.5, seconds_per_tick)) + to_chat(slime, span_danger("You feel drained!")) + + if(slime.blood_volume < BLOOD_VOLUME_BAD) + Cannibalize_Body(slime) + + regenerate_limbs?.build_all_button_icons(UPDATE_BUTTON_STATUS) + return . + +/obj/item/organ/internal/heart/slime/proc/Cannibalize_Body(mob/living/carbon/human/H) + var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() + var/obj/item/bodypart/consumed_limb + if(!length(limbs_to_consume)) + H.losebreath++ + return + if(H.num_legs) //Legs go before arms + limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) + consumed_limb = H.get_bodypart(pick(limbs_to_consume)) + consumed_limb.drop_limb() + to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!")) + qdel(consumed_limb) + H.blood_volume += 20 + +/datum/action/innate/regenerate_limbs + name = "Regenerate Limbs" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "slimeheal" + button_icon = 'icons/mob/actions/actions_slime.dmi' + background_icon_state = "bg_alien" + overlay_icon_state = "bg_alien_border" + +/datum/action/innate/regenerate_limbs/IsAvailable(feedback = FALSE) + . = ..() + if(!.) + return + var/mob/living/carbon/human/H = owner + var/list/limbs_to_heal = H.get_missing_limbs() + if(!length(limbs_to_heal)) + return FALSE + if(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + return TRUE + +/datum/action/innate/regenerate_limbs/Activate() + var/mob/living/carbon/human/H = owner + var/list/limbs_to_heal = H.get_missing_limbs() + if(!length(limbs_to_heal)) + to_chat(H, span_notice("You feel intact enough as it is.")) + return + to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]...")) + if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY) + H.regenerate_limbs() + H.blood_volume -= 40*length(limbs_to_heal) + to_chat(H, span_notice("...and after a moment you finish reforming!")) + return + else if(H.blood_volume >= 40)//We can partially heal some limbs + while(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + var/healed_limb = pick(limbs_to_heal) + H.regenerate_limb(healed_limb) + limbs_to_heal -= healed_limb + H.blood_volume -= 40 + to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!")) + return + to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!")) + +#undef JELLY_REGEN_RATE +#undef JELLY_REGEN_RATE_EMPTY +#undef BLOOD_VOLUME_LOSE_NUTRITION + +/obj/item/organ/internal/heart/synth + name = "hydraulic pump engine" + desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move." + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "heart-ipc-on" + base_icon_state = "heart-ipc" + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD // 1.5x due to synthcode.tm being weird + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_HEART + var/last_message_time = 0 + +/obj/item/organ/internal/heart/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + to_chat(owner, span_warning("Alert: Main hydraulic pump control has taken severe damage, seek maintenance immediately. Error code: HP300-10.")) + apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + if(EMP_LIGHT) + to_chat(owner, span_warning("Alert: Main hydraulic pump control has taken light damage, seek maintenance immediately. Error code: HP300-05.")) + apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + +/datum/design/synth_heart + name = "Hydraulic Pump Engine" + desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move." + id = "synth_heart" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/heart/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/surgery/organs/internal/liver.dm b/monkestation/code/modules/surgery/organs/internal/liver.dm index 8c04708a6c06..fff44411c88d 100644 --- a/monkestation/code/modules/surgery/organs/internal/liver.dm +++ b/monkestation/code/modules/surgery/organs/internal/liver.dm @@ -8,3 +8,58 @@ alcohol_tolerance = 0 liver_resistance = 0 toxTolerance = 1 //while the organ isn't damaged by doing its job, it doesnt do it very well + +/obj/item/organ/internal/liver/slime + name = "endoplasmic reticulum" + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + organ_traits = list(TRAIT_TOXINLOVER) + +/obj/item/organ/internal/liver/slime/on_life(seconds_per_tick, times_fired) + . = ..() + operated = FALSE + +/obj/item/organ/internal/liver/synth + name = "reagent processing unit" + desc = "An electronic device that processes the beneficial chemicals for the synthetic user." + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "liver-ipc" + filterToxins = FALSE //We dont filter them, we're immune to them + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_LIVER + maxHealth = 1 * STANDARD_ORGAN_THRESHOLD + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + +/obj/item/organ/internal/liver/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + to_chat(owner, span_warning("Alert: Critical! Reagent processing unit failure, seek maintenance immediately. Error Code: DR-1k")) + apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + + if(EMP_LIGHT) + to_chat(owner, span_warning("Alert: Reagent processing unit failure, seek maintenance for diagnostic. Error Code: DR-0k")) + apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + +/datum/design/synth_liver + name = "Reagent Processing Unit" + desc = "An electronic device that processes the beneficial chemicals for the synthetic user." + id = "synth_liver" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/liver/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/surgery/organs/internal/lungs.dm b/monkestation/code/modules/surgery/organs/internal/lungs.dm index 8b0b2f858738..cad2bda9eeb1 100644 --- a/monkestation/code/modules/surgery/organs/internal/lungs.dm +++ b/monkestation/code/modules/surgery/organs/internal/lungs.dm @@ -5,3 +5,62 @@ icon_state = "lungs-clock" organ_flags = ORGAN_SYNTHETIC status = ORGAN_ROBOTIC + +/obj/item/organ/internal/lungs/slime + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + safe_oxygen_min = 4 //We don't need much oxygen to subsist. + +/obj/item/organ/internal/lungs/slime/on_life(seconds_per_tick, times_fired) + . = ..() + operated = FALSE + +/obj/item/organ/internal/lungs/synth + name = "heatsink" + 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 = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "lungs-ipc" + safe_nitro_min = 0 + safe_co2_max = 0 + safe_plasma_min = 0 + safe_plasma_max = 0 + safe_oxygen_min = 0 //What are you doing man, dont breathe with those! + safe_oxygen_max = 0 + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_LUNGS + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + +/obj/item/organ/internal/lungs/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + to_chat(owner, span_warning("Alert: Critical cooling system failure! Seek maintenance immediately. Error Code: 5H-17")) + owner.adjust_bodytemperature(SYNTH_HEAVY_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT) + + if(EMP_LIGHT) + to_chat(owner, span_warning("Alert: Major cooling system failure!")) + owner.adjust_bodytemperature(SYNTH_LIGHT_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT) + +/datum/design/synth_heatsink + name = "Heatsink" + 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." + id = "synth_lungs" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/lungs/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/surgery/organs/internal/stomach.dm b/monkestation/code/modules/surgery/organs/internal/stomach.dm index 2ef0eff5e8fc..183b9758b07c 100644 --- a/monkestation/code/modules/surgery/organs/internal/stomach.dm +++ b/monkestation/code/modules/surgery/organs/internal/stomach.dm @@ -18,3 +18,80 @@ organ_flags = ORGAN_SYNTHETIC //max_charge = 7500 //charge = 7500 //old bee code + +/obj/item/organ/internal/stomach/slime + name = "golgi apparatus" + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + +/obj/item/organ/internal/stomach/slime/on_life(seconds_per_tick, times_fired) + . = ..() + operated = FALSE + +///IPCS NO LONGER ARE PURE ELECTRICAL BEINGS, any attempts to change this outside of Borbop will be denied. Thanks. +/obj/item/organ/internal/stomach/synth + name = "synthetic bio-reactor" + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "stomach-ipc" + w_class = WEIGHT_CLASS_NORMAL + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_STOMACH + maxHealth = 1 * STANDARD_ORGAN_THRESHOLD + zone = "chest" + slot = "stomach" + desc = "A specialised mini reactor, for synthetic use only. Has a low-power mode to ensure baseline functions. Without this, synthetics are unable to stay powered." + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + +/obj/item/organ/internal/stomach/synth/emp_act(severity) + . = ..() + + if(!owner || . & EMP_PROTECT_SELF) + return + + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + + switch(severity) + if(EMP_HEAVY) + owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_HEAVY_EMP_CHARGE_LOSS) + apply_organ_damage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + to_chat(owner, span_warning("Alert: Severe battery discharge!")) + + if(EMP_LIGHT) + owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_LIGHT_EMP_CHARGE_LOSS) + apply_organ_damage(SYNTH_ORGAN_LIGHT_EMP_DAMAGE, maxHealth, required_organtype = ORGAN_ROBOTIC) + to_chat(owner, span_warning("Alert: Minor battery discharge!")) + +/datum/design/synth_stomach + name = "Synthetic Bio-Reactor" + desc = "A specialised mini reactor, for synthetic use only. Has a low-power mode to ensure baseline functions. Without this, synthetics are unable to stay powered." + id = "synth_stomach" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/stomach/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE + +/obj/item/organ/internal/stomach/synth/Insert(mob/living/carbon/receiver, special, drop_if_replaced) + . = ..() + RegisterSignal(receiver, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(on_borg_charge)) + +/obj/item/organ/internal/stomach/synth/Remove(mob/living/carbon/stomach_owner, special) + . = ..() + UnregisterSignal(stomach_owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT) + +///Handles charging the synth from borg chargers +/obj/item/organ/internal/stomach/synth/proc/on_borg_charge(datum/source, amount) + SIGNAL_HANDLER + + if(owner.nutrition >= NUTRITION_LEVEL_ALMOST_FULL) + return + + amount /= 50 // Lowers the charging amount so it isn't instant + owner.nutrition = min((owner.nutrition + amount), NUTRITION_LEVEL_ALMOST_FULL) // Makes sure we don't make the synth too full, which would apply the overweight slowdown diff --git a/monkestation/code/modules/surgery/organs/internal/tongue.dm b/monkestation/code/modules/surgery/organs/internal/tongue.dm index c2a45d683494..9d87b87d5cf8 100644 --- a/monkestation/code/modules/surgery/organs/internal/tongue.dm +++ b/monkestation/code/modules/surgery/organs/internal/tongue.dm @@ -38,3 +38,57 @@ /obj/item/organ/internal/tongue/arachnid/get_possible_languages() return ..() + /datum/language/buzzwords + +/obj/item/organ/internal/tongue/jelly + zone = BODY_ZONE_CHEST + organ_flags = ORGAN_UNREMOVABLE + +/obj/item/organ/internal/tongue/jelly/get_possible_languages() + return ..() + /datum/language/slime + +/obj/item/organ/internal/tongue/synth + name = "synthetic voicebox" + desc = "A fully-functional synthetic tongue, encased in soft silicone. Features include high-resolution vocals and taste receptors." + icon = 'monkestation/code/modules/smithing/icons/ipc_organ.dmi' + icon_state = "cybertongue" + say_mod = "beeps" + attack_verb_continuous = list("beeps", "boops") + attack_verb_simple = list("beep", "boop") + modifies_speech = TRUE + taste_sensitivity = 25 // not as good as an organic tongue + maxHealth = 100 //RoboTongue! + zone = BODY_ZONE_HEAD + slot = ORGAN_SLOT_TONGUE + organ_flags = ORGAN_ROBOTIC | ORGAN_SYNTHETIC_FROM_SPECIES + +/obj/item/organ/internal/tongue/synth/get_scream_sound() + return 'monkestation/sound/voice/screams/silicon/scream_silicon.ogg' + +/obj/item/organ/internal/tongue/synth/get_laugh_sound() + return pick( + 'monkestation/sound/voice/laugh/silicon/laugh_siliconE1M0.ogg', + 'monkestation/sound/voice/laugh/silicon/laugh_siliconE1M1.ogg', + 'monkestation/sound/voice/laugh/silicon/laugh_siliconM2.ogg', + ) + +/obj/item/organ/internal/tongue/synth/can_speak_language(language) + return TRUE + +/obj/item/organ/internal/tongue/synth/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_ROBOT + +/datum/design/synth_tongue + name = "Synthetic Tongue" + desc = "A fully-functional synthetic tongue, encased in soft silicone. Features include high-resolution vocals and taste receptors." + id = "synth_tongue" + build_type = PROTOLATHE | AWAY_LATHE | MECHFAB + construction_time = 4 SECONDS + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/organ/internal/tongue/synth + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/monkestation/code/modules/smithing/ipcs/surgeries/robot_brain_healing.dm b/monkestation/code/modules/surgery/robot_brain_healing.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/surgeries/robot_brain_healing.dm rename to monkestation/code/modules/surgery/robot_brain_healing.dm diff --git a/monkestation/code/modules/smithing/ipcs/surgeries/robot_chest_repair.dm b/monkestation/code/modules/surgery/robot_chest_repair.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/surgeries/robot_chest_repair.dm rename to monkestation/code/modules/surgery/robot_chest_repair.dm diff --git a/monkestation/code/modules/smithing/ipcs/surgeries/robot_healing.dm b/monkestation/code/modules/surgery/robot_healing.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/surgeries/robot_healing.dm rename to monkestation/code/modules/surgery/robot_healing.dm diff --git a/monkestation/code/modules/smithing/ipcs/surgeries/steps.dm b/monkestation/code/modules/surgery/steps.dm similarity index 100% rename from monkestation/code/modules/smithing/ipcs/surgeries/steps.dm rename to monkestation/code/modules/surgery/steps.dm diff --git a/monkestation/icons/mob/clothing/worn_modsuit.dmi b/monkestation/icons/mob/clothing/worn_modsuit.dmi index 900e2c30e61e..9d9f37d5a897 100644 Binary files a/monkestation/icons/mob/clothing/worn_modsuit.dmi and b/monkestation/icons/mob/clothing/worn_modsuit.dmi differ diff --git a/monkestation/icons/obj/clothing/modsuits/modsuit.dmi b/monkestation/icons/obj/clothing/modsuits/modsuit.dmi index 3d550c1034cd..9be9e19751f1 100644 Binary files a/monkestation/icons/obj/clothing/modsuits/modsuit.dmi and b/monkestation/icons/obj/clothing/modsuits/modsuit.dmi differ diff --git a/monkestation/icons/obj/device.dmi b/monkestation/icons/obj/device.dmi index 10a21daaf598..669e7a795f2d 100644 Binary files a/monkestation/icons/obj/device.dmi and b/monkestation/icons/obj/device.dmi differ diff --git a/monkestation/code/modules/blueshield/icons/radio.dmi b/monkestation/icons/obj/radio.dmi similarity index 100% rename from monkestation/code/modules/blueshield/icons/radio.dmi rename to monkestation/icons/obj/radio.dmi diff --git a/monkestation/code/modules/blueshield/icons/gun.dmi b/monkestation/icons/obj/weapons/guns/tech9.dmi similarity index 100% rename from monkestation/code/modules/blueshield/icons/gun.dmi rename to monkestation/icons/obj/weapons/guns/tech9.dmi diff --git a/tgstation.dme b/tgstation.dme index 7518b42b14c8..158d44ce3893 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6631,9 +6631,7 @@ #include "monkestation\code\modules\blueshield\closet.dm" #include "monkestation\code\modules\blueshield\clothing.dm" #include "monkestation\code\modules\blueshield\gun.dm" -#include "monkestation\code\modules\blueshield\job.dm" #include "monkestation\code\modules\blueshield\landmarks.dm" -#include "monkestation\code\modules\blueshield\radio.dm" #include "monkestation\code\modules\blueshield\trim.dm" #include "monkestation\code\modules\blueshield\devices\crew_monitor.dm" #include "monkestation\code\modules\blueshield\devices\sensor.dm" @@ -7327,8 +7325,10 @@ #include "monkestation\code\modules\job_xp\milestones\botany_milestones.dm" #include "monkestation\code\modules\job_xp\preferences\base_preferences.dm" #include "monkestation\code\modules\job_xp\preferences\xp_handlers.dm" +#include "monkestation\code\modules\jobs\departments\departments.dm" #include "monkestation\code\modules\jobs\job_types\_job.dm" #include "monkestation\code\modules\jobs\job_types\barber.dm" +#include "monkestation\code\modules\jobs\job_types\blueshield.dm" #include "monkestation\code\modules\jobs\job_types\brig_physician.dm" #include "monkestation\code\modules\jobs\job_types\candysalesman.dm" #include "monkestation\code\modules\jobs\job_types\chaplain.dm" @@ -7347,7 +7347,6 @@ #include "monkestation\code\modules\jobs\job_types\skeleton.dm" #include "monkestation\code\modules\jobs\job_types\virologist.dm" #include "monkestation\code\modules\jobs\job_types\yellowclown.dm" -#include "monkestation\code\modules\jobs\job_types\departments\departments.dm" #include "monkestation\code\modules\jobs\job_types\spawner\bar_drone.dm" #include "monkestation\code\modules\library\bookcase.dm" #include "monkestation\code\modules\library\skill_learning\job_skillchips\shaft_miner.dm" @@ -7591,8 +7590,11 @@ #include "monkestation\code\modules\mob\living\carbon\human\species_type\floran.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\flypeople.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\goblin.dm" +#include "monkestation\code\modules\mob\living\carbon\human\species_type\ipc.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\lizardpeople.dm" +#include "monkestation\code\modules\mob\living\carbon\human\species_type\oozeling.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\plasmamen.dm" +#include "monkestation\code\modules\mob\living\carbon\human\species_type\satyr.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\simian.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\skeletons.dm" #include "monkestation\code\modules\mob\living\carbon\human\species_type\teratoma.dm" @@ -7879,9 +7881,7 @@ #include "monkestation\code\modules\ranching\mutations\tier3.dm" #include "monkestation\code\modules\ranching\name_tags\name_tag.dm" #include "monkestation\code\modules\ranching\satyr\abilities.dm" -#include "monkestation\code\modules\ranching\satyr\bodyparts.dm" #include "monkestation\code\modules\ranching\satyr\external_organs.dm" -#include "monkestation\code\modules\ranching\satyr\species.dm" #include "monkestation\code\modules\ranching\satyr\accessories\prefs.dm" #include "monkestation\code\modules\ranching\satyr\accessories\sprites\fluff.dm" #include "monkestation\code\modules\ranching\satyr\accessories\sprites\horns.dm" @@ -8075,15 +8075,8 @@ #include "monkestation\code\modules\smithing\assembly_bench\assembly_bench.dm" #include "monkestation\code\modules\smithing\assembly_bench\assembly_recipes\_base_recipe.dm" #include "monkestation\code\modules\smithing\assembly_bench\assembly_recipes\weapons.dm" -#include "monkestation\code\modules\smithing\ipcs\species.dm" -#include "monkestation\code\modules\smithing\ipcs\body\base_bodyparts.dm" -#include "monkestation\code\modules\smithing\ipcs\body\internal_organs.dm" #include "monkestation\code\modules\smithing\ipcs\reagents\medical_supplies.dm" #include "monkestation\code\modules\smithing\ipcs\reagents\reagents.dm" -#include "monkestation\code\modules\smithing\ipcs\surgeries\robot_brain_healing.dm" -#include "monkestation\code\modules\smithing\ipcs\surgeries\robot_chest_repair.dm" -#include "monkestation\code\modules\smithing\ipcs\surgeries\robot_healing.dm" -#include "monkestation\code\modules\smithing\ipcs\surgeries\steps.dm" #include "monkestation\code\modules\smithing\items\clothing.dm" #include "monkestation\code\modules\smithing\items\merged_material.dm" #include "monkestation\code\modules\smithing\machines\arc_forge.dm" @@ -8112,9 +8105,6 @@ #include "monkestation\code\modules\smithing\mining_changes\mineral_datums.dm" #include "monkestation\code\modules\smithing\mining_changes\mineral_sample.dm" #include "monkestation\code\modules\smithing\oozelings\actions.dm" -#include "monkestation\code\modules\smithing\oozelings\species.dm" -#include "monkestation\code\modules\smithing\oozelings\body\bodyparts.dm" -#include "monkestation\code\modules\smithing\oozelings\body\organs.dm" #include "monkestation\code\modules\smithing\research\circuits_and_research.dm" #include "monkestation\code\modules\smithing\TEG\circulators.dm" #include "monkestation\code\modules\smithing\TEG\reagents.dm" @@ -8197,6 +8187,10 @@ #include "monkestation\code\modules\surgery\hepatectomy.dm" #include "monkestation\code\modules\surgery\lobectomy.dm" #include "monkestation\code\modules\surgery\nif_debonding.dm" +#include "monkestation\code\modules\surgery\robot_brain_healing.dm" +#include "monkestation\code\modules\surgery\robot_chest_repair.dm" +#include "monkestation\code\modules\surgery\robot_healing.dm" +#include "monkestation\code\modules\surgery\steps.dm" #include "monkestation\code\modules\surgery\advanced\brainwashing.dm" #include "monkestation\code\modules\surgery\advanced\lobotomy.dm" #include "monkestation\code\modules\surgery\advanced\pacification.dm" @@ -8204,7 +8198,10 @@ #include "monkestation\code\modules\surgery\bodyparts\clockwork_bodyparts.dm" #include "monkestation\code\modules\surgery\bodyparts\ethereal_bodyparts.dm" #include "monkestation\code\modules\surgery\bodyparts\floran_bodyparts.dm" +#include "monkestation\code\modules\surgery\bodyparts\ipc_bodyparts.dm" #include "monkestation\code\modules\surgery\bodyparts\monkey_bodyparts.dm" +#include "monkestation\code\modules\surgery\bodyparts\oozeling_bodyparts.dm" +#include "monkestation\code\modules\surgery\bodyparts\satyr_bodyparts.dm" #include "monkestation\code\modules\surgery\bodyparts\teratoma_bodyparts.dm" #include "monkestation\code\modules\surgery\organs\augments.dm" #include "monkestation\code\modules\surgery\organs\autosurgeon.dm" diff --git a/tgui/packages/tgui/interfaces/common/JobToIcon.ts b/tgui/packages/tgui/interfaces/common/JobToIcon.ts index b93296c08c3a..aff948908689 100644 --- a/tgui/packages/tgui/interfaces/common/JobToIcon.ts +++ b/tgui/packages/tgui/interfaces/common/JobToIcon.ts @@ -82,6 +82,7 @@ const ALTTITLES = { Artist: BASEICONS['Assistant'], 'Off-Duty Staff': BASEICONS['Assistant'], 'Off-Duty Crew': BASEICONS['Assistant'], + 'Test Subject': BASEICONS['Assistant'], // Atmospheric Technician - fan 'Life Support Technician': BASEICONS['Atmospheric Technician'], 'Emergency Fire Technician': BASEICONS['Atmospheric Technician'], @@ -98,6 +99,10 @@ const ALTTITLES = { // Blueshield - shield-dog 'Command Bodyguard': BASEICONS['Blueshield'], 'Executive Protection Agent': BASEICONS['Blueshield'], + Bodyguard: BASEICONS['Blueshield'], + 'Revolutionary Repellent': BASEICONS['Blueshield'], + 'Heavily Armed Butler': BASEICONS['Blueshield'], + 'Honor Guard': BASEICONS['Blueshield'], // Botanist - seedling Hydroponicist: BASEICONS['Botanist'], Gardener: BASEICONS['Botanist'], @@ -110,6 +115,8 @@ const ALTTITLES = { 'Station Commander': BASEICONS['Captain'], 'Commanding Officer': BASEICONS['Captain'], 'Site Manager': BASEICONS['Captain'], + 'Criminally Underpaid Babysitter': BASEICONS['Captain'], + Princess: BASEICONS['Captain'], // Cargo Technician - box 'Warehouse Technician': BASEICONS['Cargo Technician'], 'Deck Worker': BASEICONS['Cargo Technician'], @@ -147,6 +154,7 @@ const ALTTITLES = { Butcher: BASEICONS['Cook'], 'Culinary Artist': BASEICONS['Cook'], 'Sous-Chef': BASEICONS['Cook'], + Pizzaiolo: BASEICONS['Cook'], // Coroner - skull Mortician: BASEICONS['Coroner'], 'Funeral Director': BASEICONS['Coroner'], @@ -154,6 +162,7 @@ const ALTTITLES = { Librarian: BASEICONS['Curator'], Journalist: BASEICONS['Curator'], Archivist: BASEICONS['Curator'], + 'Radio Host': BASEICONS['Curator'], // Cyborg - robot Robot: BASEICONS['Cyborg'], Android: BASEICONS['Cyborg'], @@ -198,6 +207,10 @@ const ALTTITLES = { Pantomimist: BASEICONS['Mime'], // Nanotrasen Consultant - clipboard-check 'Nanotrasen Diplomat': BASEICONS['Nanotrasen Consultant'], + 'Corporate Liaison': BASEICONS['Nanotrasen Consultant'], + 'Nanotrasen Fax Operater': BASEICONS['Nanotrasen Consultant'], + 'Nanotrasen Official': BASEICONS['Nanotrasen Consultant'], + 'Nanotrasen Informant': BASEICONS['Nanotrasen Consultant'], // Paramedic - truck-medical 'Emergency Medical Technician': BASEICONS['Paramedic'], 'Search and Rescue Technician': BASEICONS['Paramedic'], @@ -209,6 +222,7 @@ const ALTTITLES = { Convict: BASEICONS['Prisoner'], Felon: BASEICONS['Prisoner'], Inmate: BASEICONS['Prisoner'], + Gamer: BASEICONS['Prisoner'], // Psychologist - brain Psychiatrist: BASEICONS['Psychologist'], Therapist: BASEICONS['Psychologist'], @@ -220,6 +234,7 @@ const ALTTITLES = { 'Supply Foreman': BASEICONS['Quartermaster'], 'Head of Supply': BASEICONS['Quartermaster'], 'Logistics Coordinator': BASEICONS['Quartermaster'], + 'Cargyptian Overseer': BASEICONS['Quartermaster'], // Research Director - user-graduate 'Silicon Administrator': BASEICONS['Research Director'], 'Lead Researcher': BASEICONS['Research Director'], @@ -231,6 +246,7 @@ const ALTTITLES = { 'Biomechanical Engineer': BASEICONS['Roboticist'], 'Mechatronic Engineer': BASEICONS['Roboticist'], 'Apprentice Roboticist': BASEICONS['Roboticist'], + Ripperdoc: BASEICONS['Roboticist'], // Scientist - flask 'Circuitry Designer': BASEICONS['Scientist'], Xenobiologist: BASEICONS['Scientist'], @@ -250,6 +266,8 @@ const ALTTITLES = { Peacekeeper: BASEICONS['Security Officer'], 'Security Cadet': BASEICONS['Security Officer'], // Security Assistant - file-invoice-dollar + 'Correctional Officer': BASEICONS['Security Assistant'], + Deputy: BASEICONS['Security Assistant'], 'Hall Monitor': BASEICONS['Security Assistant'], 'Assistant Officer': BASEICONS['Security Assistant'], 'Professional Snitch': BASEICONS['Security Assistant'], @@ -272,7 +290,9 @@ const ALTTITLES = { 'Engineering Trainee': BASEICONS['Station Engineer'], // Virologist - virus Pathologist: BASEICONS['Virologist'], + 'Fish Doctor': BASEICONS['Virologist'], 'Junior Pathologist': BASEICONS['Virologist'], + 'Plague Doctor': BASEICONS['Virologist'], // Warden - handcuffs 'Brig Sergeant': BASEICONS['Warden'], 'Dispatch Officer': BASEICONS['Warden'],