diff --git a/baystation12.dme b/baystation12.dme
index 5d516ea75ec..aaa0bff9bfe 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1335,8 +1335,8 @@
#include "code\modules\nano\modules\power_monitor.dm"
#include "code\modules\nano\modules\rcon.dm"
#include "code\modules\organs\blood.dm"
+#include "code\modules\organs\misc.dm"
#include "code\modules\organs\organ.dm"
-#include "code\modules\organs\organ_alien.dm"
#include "code\modules\organs\organ_external.dm"
#include "code\modules\organs\organ_icon.dm"
#include "code\modules\organs\organ_internal.dm"
@@ -1344,6 +1344,11 @@
#include "code\modules\organs\pain.dm"
#include "code\modules\organs\robolimbs.dm"
#include "code\modules\organs\wound.dm"
+#include "code\modules\organs\subtypes\diona.dm"
+#include "code\modules\organs\subtypes\machine.dm"
+#include "code\modules\organs\subtypes\standard.dm"
+#include "code\modules\organs\subtypes\unbreakable.dm"
+#include "code\modules\organs\subtypes\xenos.dm"
#include "code\modules\overmap\_defines.dm"
#include "code\modules\overmap\sectors.dm"
#include "code\modules\overmap\ships\ship.dm"
@@ -1646,15 +1651,14 @@
#include "code\modules\spells\targeted\projectile\projectile.dm"
#include "code\modules\supermatter\supermatter.dm"
#include "code\modules\surgery\bones.dm"
-#include "code\modules\surgery\brainrepair.dm"
#include "code\modules\surgery\encased.dm"
-#include "code\modules\surgery\eye.dm"
#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
#include "code\modules\surgery\implant.dm"
#include "code\modules\surgery\limb_reattach.dm"
#include "code\modules\surgery\organs_internal.dm"
#include "code\modules\surgery\other.dm"
+#include "code\modules\surgery\robotics.dm"
#include "code\modules\surgery\slimes.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\tables\flipping.dm"
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 477fb04b7ad..179a470fc6b 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -97,8 +97,6 @@
if (powerlevel > 0 && !istype(A, /mob/living/carbon/slime))
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- return
stunprob *= H.species.siemens_coefficient
diff --git a/code/datums/disease.dm b/code/datums/disease.dm
index 398dc73bbbc..606acdef99e 100644
--- a/code/datums/disease.dm
+++ b/code/datums/disease.dm
@@ -53,14 +53,15 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
// if hidden[2] is true, then virus is hidden from PANDEMIC machine
/datum/disease/proc/stage_act()
+
+ // Some species are immune to viruses entirely.
+ if(affected_mob && istype(affected_mob, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = affected_mob
+ if(H.species.virus_immune)
+ cure()
+ return
age++
var/cure_present = has_cure()
- //world << "[cure_present]"
-
- if(carrier&&!cure_present)
- //world << "[affected_mob] is carrier"
- return
-
spread = (cure_present?"Remissive":initial_spread)
if(stage > max_stages)
stage = max_stages
@@ -126,7 +127,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
source = affected_mob
else //no source and no mob affected. Rogue disease. Break
return
-
+
if(affected_mob.reagents != null)
if(affected_mob)
if(affected_mob.reagents.has_reagent("spaceacillin"))
diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm
index 9fe4226e5bb..bd436ceaf8e 100644
--- a/code/game/antagonist/alien/borer.dm
+++ b/code/game/antagonist/alien/borer.dm
@@ -33,7 +33,10 @@ var/datum/antagonist/xenos/borer/borers
/datum/antagonist/xenos/borer/proc/get_hosts()
var/list/possible_hosts = list()
for(var/mob/living/carbon/human/H in mob_list)
- if(H.stat != 2 && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms())
+ var/obj/item/organ/external/head/head = H.get_organ("head")
+ if(head.status & ORGAN_ROBOT)
+ continue
+ if(H.stat != DEAD && !H.has_brain_worms())
possible_hosts |= H
return possible_hosts
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 99a2dc6607a..6a82c2bf5c1 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -106,7 +106,7 @@
if(NOCLONE in T.mutations)
return
- if(T.species && T.species.flags & NO_BLOOD)
+ if(T.species.flags & NO_BLOOD)
return
// If the human is losing too much blood, beep.
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index d41ab317d96..98cc92380c7 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -176,8 +176,11 @@
R.adjustBruteLoss(-1)
if(wire_rate && R.getFireLoss())
R.adjustFireLoss(-1)
- else
- update_use_power(1)
+ else if(istype(occupant, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = occupant
+ if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450)
+ H.nutrition = min(H.nutrition+10, 450)
+ update_use_power(1)
/obj/machinery/recharge_station/proc/go_out()
if(!(occupant))
@@ -209,30 +212,42 @@
if(!user)
return
- if(!(istype(user, /mob/living/silicon/robot)))
+ var/can_accept_user
+ if(istype(user, /mob/living/silicon/robot))
+
+ var/mob/living/silicon/robot/R = user
+
+ if(R.stat == 2)
+ //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
+ return
+ if(occupant)
+ R << "The cell is already occupied!"
+ return
+ if(!R.cell)
+ R << "Without a powercell, you can't be recharged."
+ //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
+ return
+ can_accept_user = 1
+
+ else if(istype(user, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(!isnull(H.internal_organs_by_name["cell"]))
+ can_accept_user = 1
+
+ if(!can_accept_user)
user << "Only non-organics may enter the recharger!"
return
- var/mob/living/silicon/robot/R = user
- if(R.stat == 2)
- //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
- return
- if(occupant)
- R << "The cell is already occupied!"
- return
- if(!R.cell)
- R << "Without a powercell, you can't be recharged."
- //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
- return
- R.stop_pulling()
- if(R.client)
- R.client.perspective = EYE_PERSPECTIVE
- R.client.eye = src
- R.loc = src
- occupant = R
+
+ user.stop_pulling()
+ if(user.client)
+ user.client.perspective = EYE_PERSPECTIVE
+ user.client.eye = src
+ user.loc = src
+ occupant = user
/*for(var/obj/O in src)
O.loc = loc*/
- add_fingerprint(R)
+ add_fingerprint(user)
build_icon()
update_use_power(1)
return
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index a29d39743ed..54fd83b162e 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -93,7 +93,7 @@ REAGENT SCANNER
return
user.visible_message(" [user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.")
- if (!istype(M, /mob/living/carbon) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
+ if (!istype(M, /mob/living/carbon) || ishuman(M))
//these sensors are designed for organic life
user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR")
user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index d59a1cdea57..8d8076cbabd 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -106,14 +106,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(location)
location.hotspot_expose(700, 5)
if(reagents && reagents.total_volume) // check if it has any reagents at all
- if(iscarbon(loc))
- var/mob/living/carbon/C = loc
- if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob
- if(istype(C, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = C
- if(H.species.flags & IS_SYNTHETIC)
- return
-
+ if(ishuman(loc))
+ var/mob/living/carbon/human/C = loc
+ if (src == C.wear_mask && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob
reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.2) // Most of it is not inhaled... balance reasons.
else // else just remove some of the reagents
reagents.remove_any(REM)
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index 6c2eb7ced35..cf7ebba2b44 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -67,7 +67,7 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC || (H.species.siemens_coefficient<0.5)) //Thick skin.
+ if(H.species.siemens_coefficient<0.5) //Thick skin.
return
if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) )
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 0c563215c73..1cd40d6c890 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -81,7 +81,8 @@
return
/obj/item/weapon/screwdriver/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M)) return ..()
+ if(!istype(M) || user.a_intent == "help")
+ return ..()
if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
return ..()
if((CLUMSY in user.mutations) && prob(50))
@@ -329,8 +330,6 @@
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
if(!E)
return
- if(H.species.flags & IS_SYNTHETIC)
- return
switch(safety)
if(1)
usr << "\red Your eyes sting a little."
@@ -427,16 +426,12 @@
if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
return ..()
- if(istype(M,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- if(M == user)
- user << "\red You can't repair damage to your own body - it's against OH&S."
- return
-
if(S.brute_dam)
- S.heal_damage(15,0,0,1)
- user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.name] with \the [src].")
+ if(S.brute_dam < ROBOLIMB_SELF_REPAIR_CAP)
+ S.heal_damage(15,0,0,1)
+ user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.name] with \the [src].")
+ else
+ user << "\red The damage is far too severe to patch over externally."
return
else
user << "Nothing to fix!"
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index fcbd8902638..0848c17a119 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -634,10 +634,6 @@ datum/preferences
dat += "Has a variety of eye colours."
if(current_species.flags & IS_PLANT)
dat += "Has a plantlike physiology."
- if(current_species.flags & IS_SYNTHETIC)
- dat += "Is machine-based."
- if(current_species.flags & REGENERATES_LIMBS)
- dat += "Has a plantlike physiology."
dat += ""
dat += ""
dat += "
"
diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm
index d5900769b35..bb343c0e7ff 100644
--- a/code/modules/mob/language/station.dm
+++ b/code/modules/mob/language/station.dm
@@ -94,6 +94,25 @@
else
return ..()
+/datum/language/machine
+ name = "Encoded Audio Language"
+ desc = "A language of encoded tones that allow for IPCs to communicate auditorily between each other in a manner that allows for easier transfer of information."
+ speech_verb = "beeps"
+ ask_verb = "beeps"
+ exclaim_verb = "loudly beeps"
+ colour = "changeling"
+ key = "6"
+ flags = RESTRICTED | NO_STUTTER
+ syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz")
+ space_chance = 10
+
+/datum/language/machine/get_random_name()
+ if(prob(70))
+ name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
+ else
+ name = pick(ai_names)
+ return name
+
//Syllable Lists
/*
This list really long, mainly because I can't make up my mind about which mandarin syllables should be removed,
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 486916821bc..b12fce33f8d 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -92,4 +92,4 @@
desc = "A tightly furled roll of paper, covered with indecipherable runes."
robotic = 2
icon = 'icons/obj/wizard.dmi'
- icon_state = "scroll"
\ No newline at end of file
+ icon_state = "scroll"
diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm
index b467b88cd2e..62f14da4996 100644
--- a/code/modules/mob/living/carbon/breathe.dm
+++ b/code/modules/mob/living/carbon/breathe.dm
@@ -2,14 +2,14 @@
/mob/living/carbon/proc/breathe()
//if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
- if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
-
+ if(species && (species.flags & NO_BREATHE)) return
+
var/datum/gas_mixture/breath = null
-
+
//First, check if we can breathe at all
if(health < config.health_threshold_crit && !(CE_STABLE in chem_effects)) //crit aka circulatory shock
losebreath++
-
+
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
@@ -17,9 +17,9 @@
else
//Okay, we can breathe, now check if we can get air
breath = get_breath_from_internal() //First, check for air from internals
- if(!breath)
+ if(!breath)
breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location
-
+
handle_breath(breath)
handle_post_breath(breath)
@@ -40,15 +40,15 @@
/mob/living/carbon/proc/get_breath_from_environment(var/volume_needed=BREATH_VOLUME)
var/datum/gas_mixture/breath = null
-
+
var/datum/gas_mixture/environment
if(loc)
environment = loc.return_air_for_internal_lifeform()
-
+
if(environment)
breath = environment.remove_volume(volume_needed)
handle_chemical_smoke(environment) //handle chemical smoke while we're at it
-
+
if(breath)
//handle mask filtering
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index dad4e902446..d6510c2bf84 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -270,9 +270,8 @@
if(temp)
if(temp.status & ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
- if(!species.flags & IS_SYNTHETIC)
- wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]!\n"
- continue
+ wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]!\n"
+ continue
else
wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!\n"
else if(temp.wounds.len > 0 || temp.open)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 02f198e9dd1..cb5b1bdf847 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -746,10 +746,17 @@
xylophone=0
return
+/mob/living/carbon/human/proc/check_has_mouth()
+ // Todo, check stomach organ when implemented.
+ var/obj/item/organ/external/head/H = get_organ("head")
+ if(!H || !H.can_intake_reagents)
+ return 0
+ return 1
+
/mob/living/carbon/human/proc/vomit()
- if(species.flags & IS_SYNTHETIC)
- return //Machines don't throw up.
+ if(!check_has_mouth())
+ return
if(!lastpuke)
lastpuke = 1
@@ -1217,16 +1224,26 @@
else
target_zone = user.zone_sel.selecting
- switch(target_zone)
- if("head")
- if(head && head.flags & THICKMATERIAL)
- . = 0
- else
- if(wear_suit && wear_suit.flags & THICKMATERIAL)
- . = 0
+ var/obj/item/organ/external/affecting = get_organ(target_zone)
+ var/fail_msg
+ if(!affecting)
+ . = 0
+ fail_msg = "They are missing that limb."
+ else if (affecting.status & ORGAN_ROBOT)
+ . = 0
+ fail_msg = "That limb is robotic."
+ else
+ switch(target_zone)
+ if("head")
+ if(head && head.flags & THICKMATERIAL)
+ . = 0
+ else
+ if(wear_suit && wear_suit.flags & THICKMATERIAL)
+ . = 0
if(!. && error_msg && user)
- // Might need re-wording.
- user << "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into."
+ if(!fail_msg)
+ fail_msg = "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into."
+ user << "[fail_msg]"
/mob/living/carbon/human/print_flavor_text(var/shrink = 1)
var/list/equipment = list(src.head,src.wear_mask,src.glasses,src.w_uniform,src.wear_suit,src.gloves,src.shoes)
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index a198daa1125..21a386b5cf1 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -48,6 +48,12 @@
switch(M.a_intent)
if(I_HELP)
if(istype(H) && health < config.health_threshold_crit && health > config.health_threshold_dead)
+ if(!H.check_has_mouth())
+ H << "You don't have a mouth, you cannot perform CPR!"
+ return
+ if(!check_has_mouth())
+ H << "They don't have a mouth, you cannot perform CPR!"
+ return
if((H.head && (H.head.flags & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags & MASKCOVERSMOUTH)))
H << "Remove your mask!"
return 0
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 04ca8922257..298c4fa6251 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -142,12 +142,12 @@
..()
/mob/living/carbon/human/getCloneLoss()
- if(species.flags & (IS_SYNTHETIC | NO_SCAN))
+ if(species.flags & (NO_SCAN))
cloneloss = 0
return ..()
/mob/living/carbon/human/setCloneLoss(var/amount)
- if(species.flags & (IS_SYNTHETIC | NO_SCAN))
+ if(species.flags & (NO_SCAN))
cloneloss = 0
else
..()
@@ -155,7 +155,7 @@
/mob/living/carbon/human/adjustCloneLoss(var/amount)
..()
- if(species.flags & (IS_SYNTHETIC | NO_SCAN))
+ if(species.flags & (NO_SCAN))
cloneloss = 0
return
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 994cab11f6f..675d3c41df6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -179,12 +179,6 @@ emp_act
for(var/obj/O in src)
if(!O) continue
O.emp_act(severity)
- for(var/obj/item/organ/external/O in organs)
- if(O.status & ORGAN_DESTROYED) continue
- O.emp_act(severity)
- for(var/obj/item/organ/I in O.internal_organs)
- if(I.robotic == 0) continue
- I.emp_act(severity)
..()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 84a6fb82902..896f57878cd 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -258,9 +258,6 @@
proc/handle_mutations_and_radiation()
- if(species.flags & IS_SYNTHETIC) //Robots don't suffer from mutations or radloss.
- return
-
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || (prob(1)))
heal_organ_damage(0,1)
@@ -709,9 +706,9 @@
*/
proc/stabilize_body_temperature()
- if (species.flags & IS_SYNTHETIC)
- bodytemperature += species.synth_temp_gain //just keep putting out heat.
- return
+
+ if (species.passive_temp_gain) // We produce heat naturally.
+ bodytemperature += species.passive_temp_gain
var/body_temperature_difference = species.body_temperature - bodytemperature
@@ -858,15 +855,16 @@
proc/handle_chemicals_in_body()
- if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents.
+ if(reagents)
chem_effects.Cut()
analgesic = 0
var/alien = 0
if(species && species.reagent_tag)
alien = species.reagent_tag
touching.metabolize(alien, CHEM_TOUCH)
- ingested.metabolize(alien, CHEM_INGEST)
- reagents.metabolize(alien, CHEM_BLOOD)
+ if(!(species.flags & NO_BLOOD))
+ ingested.metabolize(alien, CHEM_INGEST)
+ reagents.metabolize(alien, CHEM_BLOOD)
if(CE_PAINKILLER in chem_effects)
analgesic = chem_effects[CE_PAINKILLER]
@@ -931,7 +929,8 @@
take_overall_damage(2,0)
traumatic_shock++
- if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems()
+ // TODO: stomach and bloodstream organ.
+ handle_trace_chems()
updatehealth()
@@ -1133,7 +1132,7 @@
if(damageoverlay.overlays)
damageoverlay.overlays = list()
-
+
if(stat == UNCONSCIOUS)
//Critical damage passage overlay
if(health <= 0)
@@ -1268,7 +1267,7 @@
if(2) healths.icon_state = "health7"
else
//switch(health - halloss)
- switch(100 - ((species && species.flags & NO_PAIN & !IS_SYNTHETIC) ? 0 : traumatic_shock))
+ switch(100 - ((species.flags & NO_PAIN) ? 0 : traumatic_shock))
if(100 to INFINITY) healths.icon_state = "health0"
if(80 to 100) healths.icon_state = "health1"
if(60 to 80) healths.icon_state = "health2"
@@ -1504,7 +1503,8 @@
if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load)
- if(species && species.flags & NO_BLOOD) return PULSE_NONE //No blood, no pulse.
+ if(species && species.flags & NO_BLOOD)
+ return PULSE_NONE //No blood, no pulse.
if(stat == DEAD)
return PULSE_NONE //that's it, you're dead, nothing can influence your pulse
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 1bc6ca880a5..057fabcb5fc 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -29,6 +29,7 @@
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/is_small
var/show_ssd = 1
+ var/virus_immune
// Language/culture vars.
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
@@ -69,7 +70,7 @@
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 3 above this point.
- var/synth_temp_gain = 0 // IS_SYNTHETIC species will gain this much temperature every second
+ var/passive_temp_gain = 0 // Species will gain this much temperature every second
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
@@ -213,13 +214,6 @@
for(var/obj/item/organ/external/O in H.organs)
O.owner = H
- if(flags & IS_SYNTHETIC)
- for(var/obj/item/organ/external/E in H.organs)
- if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
- E.robotize()
- for(var/obj/item/organ/I in H.internal_organs)
- I.robotize()
-
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
var/t_him = "them"
diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm
index 6d5e918a957..46a7e9f5f53 100644
--- a/code/modules/mob/living/carbon/human/species/station/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/station/slime.dm
@@ -8,7 +8,7 @@
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
- flags = IS_RESTRICTED | NO_BLOOD | NO_SCAN | NO_SLIP | NO_BREATHE
+ flags = IS_RESTRICTED | NO_SCAN | NO_SLIP | NO_BREATHE
siemens_coefficient = 3
darksight = 3
@@ -30,17 +30,17 @@
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
has_limbs = list(
- "chest" = list("path" = /obj/item/organ/external/chest/slime),
- "groin" = list("path" = /obj/item/organ/external/groin/slime),
- "head" = list("path" = /obj/item/organ/external/head/slime),
- "l_arm" = list("path" = /obj/item/organ/external/arm/slime),
- "r_arm" = list("path" = /obj/item/organ/external/arm/right/slime),
- "l_leg" = list("path" = /obj/item/organ/external/leg/slime),
- "r_leg" = list("path" = /obj/item/organ/external/leg/right/slime),
- "l_hand" = list("path" = /obj/item/organ/external/hand/slime),
- "r_hand" = list("path" = /obj/item/organ/external/hand/right/slime),
- "l_foot" = list("path" = /obj/item/organ/external/foot/slime),
- "r_foot" = list("path" = /obj/item/organ/external/foot/right/slime)
+ "chest" = list("path" = /obj/item/organ/external/chest/unbreakable),
+ "groin" = list("path" = /obj/item/organ/external/groin/unbreakable),
+ "head" = list("path" = /obj/item/organ/external/head/unbreakable),
+ "l_arm" = list("path" = /obj/item/organ/external/arm/unbreakable),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right/unbreakable),
+ "l_leg" = list("path" = /obj/item/organ/external/leg/unbreakable),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right/unbreakable),
+ "l_hand" = list("path" = /obj/item/organ/external/hand/unbreakable),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right/unbreakable),
+ "l_foot" = list("path" = /obj/item/organ/external/foot/unbreakable),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right/unbreakable)
)
/datum/species/slime/handle_death(var/mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index 985a5dac097..c7cbe57a79d 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -195,7 +195,7 @@
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
- flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | REGENERATES_LIMBS
+ flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP
blood_color = "#004400"
flesh_color = "#907E4A"
@@ -231,15 +231,22 @@
else
qdel(D)
- H.visible_message("\red[H] splits apart with a wet slithering noise!")
+ H.visible_message("[H] splits apart with a wet slithering noise!")
/datum/species/machine
name = "Machine"
name_plural = "machines"
+ blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \
+ robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \
+ to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \
+ generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \
+ inhuman in outlook and perspective."
+
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
- language = "Tradeband"
+
+ language = "Encoded Audio Language"
unarmed_types = list(/datum/unarmed_attack/punch)
rarity_value = 2
@@ -254,24 +261,41 @@
cold_level_2 = -1
cold_level_3 = -1
- heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
+ heat_level_1 = 500 // Gives them about 25 seconds in space before taking damage
heat_level_2 = 1000
heat_level_3 = 2000
- synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
+ passive_temp_gain = 10 // This should cause IPCs to stabilize at ~80 C in a 20 C environment.
+ siemens_coefficient = 0 // Insulated.
- flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
+ flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_POISON
blood_color = "#1F181F"
flesh_color = "#575757"
+ virus_immune = 1
+ reagent_tag = IS_MACHINE
- has_organ = list() //TODO: Positronic brain.
+ has_organ = list(
+ "brain" = /obj/item/organ/mmi_holder/posibrain,
+ "cell" = /obj/item/organ/cell
+ )
-/datum/species/machine/equip_survival_gear(var/mob/living/carbon/human/H)
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest/ipc),
+ "groin" = list("path" = /obj/item/organ/external/groin/ipc),
+ "head" = list("path" = /obj/item/organ/external/head/ipc),
+ "l_arm" = list("path" = /obj/item/organ/external/arm/ipc),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc),
+ "l_leg" = list("path" = /obj/item/organ/external/leg/ipc),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc),
+ "l_hand" = list("path" = /obj/item/organ/external/hand/ipc),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc),
+ "l_foot" = list("path" = /obj/item/organ/external/foot/ipc),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc)
+ )
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
..()
- if(flags & IS_SYNTHETIC)
- H.h_style = ""
- spawn(100)
- if(H) H.update_hair()
+ H.h_style = ""
+ spawn(100)
+ if(H) H.update_hair()
diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm
index 75556cf3041..812a882efe9 100644
--- a/code/modules/mob/living/silicon/robot/analyzer.dm
+++ b/code/modules/mob/living/silicon/robot/analyzer.dm
@@ -26,54 +26,70 @@
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue Body Temperature: ???", 1)
return
- if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- user << "\red You don't have the dexterity to do this!"
- return
- if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
+
+ var/scan_type
+ if(istype(M, /mob/living/silicon/robot))
+ scan_type = "robot"
+ else if(istype(M, /mob/living/carbon/human))
+ scan_type = "prosthetics"
+ else
user << "\red You can't analyze non-robotic things!"
return
- user.visible_message(" [user] has analyzed [M]'s components."," You have analyzed [M]'s components.")
- var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
- var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
- user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]")
- user.show_message("\t Key: Electronics/Brute", 1)
- user.show_message("\t Damage Specifics: [BU] - [BR]")
- if(M.tod && M.stat == DEAD)
- user.show_message("\blue Time of Disable: [M.tod]")
+ user.visible_message("\The [user] has analyzed [M]'s components.","You have analyzed [M]'s components.")
+ switch(scan_type)
+ if("robot")
+ var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
+ var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
+ user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]")
+ user.show_message("\t Key: Electronics/Brute", 1)
+ user.show_message("\t Damage Specifics: [BU] - [BR]")
+ if(M.tod && M.stat == DEAD)
+ user.show_message("\blue Time of Disable: [M.tod]")
+ var/mob/living/silicon/robot/H = M
+ var/list/damaged = H.get_damaged_components(1,1,1)
+ user.show_message("\blue Localized Damage:",1)
+ if(length(damaged)>0)
+ for(var/datum/robot_component/org in damaged)
+ user.show_message(text("\blue \t []: [][] - [] - [] - []", \
+ capitalize(org.name), \
+ (org.installed == -1) ? "DESTROYED " :"",\
+ (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
+ (org.brute_damage > 0) ? "[org.brute_damage]" :0, \
+ (org.toggled) ? "Toggled ON" : "Toggled OFF",\
+ (org.powered) ? "Power ON" : "Power OFF"),1)
+ else
+ user.show_message("\blue \t Components are OK.",1)
+ if(H.emagged && prob(5))
+ user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
+ user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
- if (istype(M, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/H = M
- var/list/damaged = H.get_damaged_components(1,1,1)
- user.show_message("\blue Localized Damage:",1)
- if(length(damaged)>0)
- for(var/datum/robot_component/org in damaged)
- user.show_message(text("\blue \t []: [][] - [] - [] - []", \
- capitalize(org.name), \
- (org.installed == -1) ? "DESTROYED " :"",\
- (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
- (org.brute_damage > 0) ? "[org.brute_damage]" :0, \
- (org.toggled) ? "Toggled ON" : "Toggled OFF",\
- (org.powered) ? "Power ON" : "Power OFF"),1)
- else
- user.show_message("\blue \t Components are OK.",1)
- if(H.emagged && prob(5))
- user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
+ if("prosthetics")
+ var/mob/living/carbon/human/H = M
+ user << "Analyzing Results for \the [H]:"
+ user << "Key: Electronics/Brute"
- if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
- var/mob/living/carbon/human/H = M
- var/list/damaged = H.get_damaged_organs(1,1)
- user.show_message("\blue Localized Damage, Brute/Electronics:",1)
- if(length(damaged)>0)
- for(var/obj/item/organ/external/org in damaged)
- user.show_message(text("\blue \t []: [] - []", \
- capitalize(org.name), \
- (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
- (org.burn_dam > 0) ? "[org.burn_dam]" :0),1)
- else
- user.show_message("\blue \t Components are OK.",1)
-
- user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
+ user << "External prosthetics:"
+ var/organ_found
+ if(H.internal_organs.len)
+ for(var/obj/item/organ/external/E in H.organs)
+ if(!(E.status & ORGAN_ROBOT))
+ continue
+ organ_found = 1
+ user << "[E.name]: [E.brute_dam] [E.burn_dam]"
+ if(!organ_found)
+ user << "No prosthetics located."
+ user << "
"
+ user << "Internal prosthetics:"
+ organ_found = null
+ if(H.internal_organs.len)
+ for(var/obj/item/organ/O in H.internal_organs)
+ if(!(O.status & ORGAN_ROBOT))
+ continue
+ organ_found = 1
+ user << "[O.name]: [O.damage]"
+ if(!organ_found)
+ user << "No prosthetics located."
src.add_fingerprint(user)
return
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 17def087b35..79115b61b29 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -104,7 +104,11 @@
return 0
/mob/living/carbon/human/isSynthetic()
- return species.flags & IS_SYNTHETIC
+ // If they are 100% robotic, they count as synthetic.
+ for(var/obj/item/organ/external/E in organs)
+ if(!(E.status & ORGAN_ROBOT))
+ return 0
+ return 1
/mob/living/silicon/isSynthetic()
return 1
diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm
index 272f43b790b..70c2281bb30 100644
--- a/code/modules/organs/blood.dm
+++ b/code/modules/organs/blood.dm
@@ -214,7 +214,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//Transfers blood from reagents to vessel, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount)
- if(species && species.flags & NO_BLOOD)
+ if(species.flags & NO_BLOOD)
reagents.add_reagent("blood", amount, injected.data)
reagents.update_total()
return
diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm
new file mode 100644
index 00000000000..a330e307a38
--- /dev/null
+++ b/code/modules/organs/misc.dm
@@ -0,0 +1,70 @@
+//CORTICAL BORER ORGANS.
+/obj/item/organ/borer/process()
+
+ // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss.
+ for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine"))
+ if(owner.reagents.get_reagent_amount(chem) < 3)
+ owner.reagents.add_reagent(chem, 5)
+
+ // They're also super gross and ooze ichor.
+ if(prob(5))
+ var/mob/living/carbon/human/H = owner
+ if(!istype(H))
+ return
+
+ var/datum/reagent/blood/B = locate(/datum/reagent/blood) in H.vessel.reagent_list
+ blood_splatter(H,B,1)
+ var/obj/effect/decal/cleanable/blood/splatter/goo = locate() in get_turf(owner)
+ if(goo)
+ goo.name = "husk ichor"
+ goo.desc = "It's thick and stinks of decay."
+ goo.basecolor = "#412464"
+ goo.update_icon()
+
+/obj/item/organ/borer
+ name = "cortical borer"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "borer"
+ organ_tag = "brain"
+ desc = "A disgusting space slug."
+ parent_organ = "head"
+ vital = 1
+
+/obj/item/organ/borer/removed(var/mob/living/user)
+
+ ..()
+
+ var/mob/living/simple_animal/borer/B = owner.has_brain_worms()
+ if(B)
+ B.leave_host()
+ B.ckey = owner.ckey
+
+ spawn(0)
+ qdel(src)
+
+//VOX ORGANS.
+/obj/item/organ/stack
+ name = "cortical stack"
+ parent_organ = "head"
+ robotic = 2
+ vital = 1
+ var/backup_time = 0
+ var/datum/mind/backup
+
+/obj/item/organ/stack/process()
+ if(owner && owner.stat != DEAD && !is_broken())
+ backup_time = world.time
+ if(owner.mind) backup = owner.mind
+
+/obj/item/organ/stack/vox
+
+/obj/item/organ/stack/vox/stack
+
+/obj/item/organ/stack
+ name = "cortical stack"
+ icon_state = "brain-prosthetic"
+ organ_tag = "stack"
+ robotic = 2
+
+/obj/item/organ/stack/vox
+ name = "vox cortical stack"
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 405c058a23d..9f94656806d 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -220,31 +220,17 @@ var/list/organ_cache = list()
min_broken_damage = 35
/obj/item/organ/emp_act(severity)
- switch(robotic)
- if(0)
+ if(!(status & ORGAN_ROBOT))
+ return
+ switch (severity)
+ if (1.0)
+ take_damage(0,20)
return
- if(1)
- switch (severity)
- if (1.0)
- take_damage(20,0)
- return
- if (2.0)
- take_damage(7,0)
- return
- if(3.0)
- take_damage(3,0)
- return
- if(2)
- switch (severity)
- if (1.0)
- take_damage(40,0)
- return
- if (2.0)
- take_damage(15,0)
- return
- if(3.0)
- take_damage(10,0)
- return
+ if (2.0)
+ take_damage(0,7)
+ return
+ if(3.0)
+ take_damage(0,3)
/obj/item/organ/proc/removed(var/mob/living/user)
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 0655bb6deb4..ecb0cb9ca2b 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -141,20 +141,11 @@
/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
if((brute <= 0) && (burn <= 0))
return 0
-
if(status & ORGAN_DESTROYED)
return 0
if(status & ORGAN_ROBOT )
-
var/brmod = 0.66
var/bumod = 0.66
-
- if(istype(owner,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = owner
- if(H.species && H.species.flags & IS_SYNTHETIC)
- brmod = H.species.brute_mod
- bumod = H.species.burn_mod
-
brute *= brmod //~2/3 damage for ROBOLIMBS
burn *= bumod //~2/3 damage for ROBOLIMBS
@@ -322,10 +313,14 @@ This function completely restores a damaged organ to perfect condition.
var/datum/wound/W = pick(compatible_wounds)
W.open_wound(damage)
if(prob(25))
- //maybe have a separate message for BRUISE type damage?
- owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\
- "\red The wound on your [name] widens with a nasty ripping noise.",\
- "You hear a nasty ripping noise, as if flesh is being torn apart.")
+ if(status & ORGAN_ROBOT)
+ owner.visible_message("\red The damage to [owner.name]'s [name] worsens.",\
+ "\red The damage to your [name] worsens.",\
+ "You hear the screech of abused metal.")
+ else
+ owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\
+ "\red The wound on your [name] widens with a nasty ripping noise.",\
+ "You hear a nasty ripping noise, as if flesh is being torn apart.")
return
//Creating wound
@@ -354,7 +349,7 @@ This function completely restores a damaged organ to perfect condition.
//Determines if we even need to process this organ.
/obj/item/organ/external/proc/need_process()
- if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status.
+ if(status & (ORGAN_CUT_AWAY|ORGAN_GAUZED|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED))
return 1
if(brute_dam || burn_dam)
return 1
@@ -981,165 +976,3 @@ Note that amputating the affected organ does in fact remove the infection from t
if(6 to INFINITY)
flavor_text += "a ton of [wound]\s"
return english_list(flavor_text)
-/****************************************************
- ORGAN DEFINES
-****************************************************/
-
-/obj/item/organ/external/chest
- name = "upper body"
- limb_name = "chest"
- icon_name = "torso"
- health = 100
- min_broken_damage = 35
- body_part = UPPER_TORSO
- vital = 1
- amputation_point = "spine"
- joint = "neck"
- dislocated = -1
- gendered_icon = 1
- cannot_amputate = 1
- parent_organ = null
- encased = "ribcage"
-
-/obj/item/organ/external/groin
- name = "lower body"
- limb_name = "groin"
- icon_name = "groin"
- health = 100
- min_broken_damage = 35
- body_part = LOWER_TORSO
- vital = 1
- parent_organ = "chest"
- amputation_point = "lumbar"
- joint = "hip"
- dislocated = -1
- gendered_icon = 1
-
-/obj/item/organ/external/arm
- limb_name = "l_arm"
- name = "left arm"
- icon_name = "l_arm"
- health = 50
- min_broken_damage = 30
- body_part = ARM_LEFT
- parent_organ = "chest"
- joint = "left elbow"
- amputation_point = "left shoulder"
- can_grasp = 1
-
-/obj/item/organ/external/arm/right
- limb_name = "r_arm"
- name = "right arm"
- icon_name = "r_arm"
- body_part = ARM_RIGHT
- joint = "right elbow"
- amputation_point = "right shoulder"
-
-/obj/item/organ/external/leg
- limb_name = "l_leg"
- name = "left leg"
- icon_name = "l_leg"
- health = 50
- min_broken_damage = 30
- body_part = LEG_LEFT
- icon_position = LEFT
- parent_organ = "groin"
- joint = "left knee"
- amputation_point = "left hip"
- can_stand = 1
-
-/obj/item/organ/external/leg/right
- limb_name = "r_leg"
- name = "right leg"
- icon_name = "r_leg"
- body_part = LEG_RIGHT
- icon_position = RIGHT
- joint = "right knee"
- amputation_point = "right hip"
-
-/obj/item/organ/external/foot
- limb_name = "l_foot"
- name = "left foot"
- icon_name = "l_foot"
- health = 30
- min_broken_damage = 15
- body_part = FOOT_LEFT
- icon_position = LEFT
- parent_organ = "l_leg"
- joint = "left ankle"
- amputation_point = "left ankle"
- can_stand = 1
-
-/obj/item/organ/external/foot/removed()
- if(owner) owner.u_equip(owner.shoes)
- ..()
-
-/obj/item/organ/external/foot/right
- limb_name = "r_foot"
- name = "right foot"
- icon_name = "r_foot"
- body_part = FOOT_RIGHT
- icon_position = RIGHT
- parent_organ = "r_leg"
- joint = "right ankle"
- amputation_point = "right ankle"
-
-/obj/item/organ/external/hand
- limb_name = "l_hand"
- name = "left hand"
- icon_name = "l_hand"
- health = 30
- min_broken_damage = 15
- body_part = HAND_LEFT
- parent_organ = "l_arm"
- joint = "left wrist"
- amputation_point = "left wrist"
- can_grasp = 1
-
-/obj/item/organ/external/hand/removed()
- owner.u_equip(owner.gloves)
- ..()
-
-/obj/item/organ/external/hand/right
- limb_name = "r_hand"
- name = "right hand"
- icon_name = "r_hand"
- body_part = HAND_RIGHT
- parent_organ = "r_arm"
- joint = "right wrist"
- amputation_point = "right wrist"
-
-/obj/item/organ/external/head
- limb_name = "head"
- icon_name = "head"
- name = "head"
- health = 75
- min_broken_damage = 35
- body_part = HEAD
- vital = 1
- parent_organ = "chest"
- joint = "jaw"
- amputation_point = "neck"
- gendered_icon = 1
- encased = "skull"
-
-/obj/item/organ/external/head/removed()
- if(owner)
- name = "[owner.real_name]'s head"
- owner.u_equip(owner.glasses)
- owner.u_equip(owner.head)
- owner.u_equip(owner.l_ear)
- owner.u_equip(owner.r_ear)
- owner.u_equip(owner.wear_mask)
- spawn(1)
- owner.update_hair()
- ..()
-
-/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
- ..(brute, burn, sharp, edge, used_weapon, forbidden_limbs)
- if (!disfigured)
- if (brute_dam > 40)
- if (prob(50))
- disfigure("brute")
- if (burn_dam > 40)
- disfigure("burn")
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index d25ce2f5a26..281cd0c0162 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -99,7 +99,7 @@ var/global/list/limb_icon_cache = list()
if(skeletal)
mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]")
- else if ((status & ORGAN_ROBOT) && !(species && species.flags & IS_SYNTHETIC))
+ else if (status & ORGAN_ROBOT)
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
else
if (status & ORGAN_MUTATED)
diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm
index bb2d571f5d7..87da7f03534 100644
--- a/code/modules/organs/robolimbs.dm
+++ b/code/modules/organs/robolimbs.dm
@@ -36,3 +36,9 @@ var/global/datum/robolimb/basic_robolimb
company = "Xion Manufacturing Group"
desc = "This limb has a minimalist black and red casing."
icon = 'icons/mob/human_races/cyberlimbs/xion.dmi'
+
+/datum/robolimb/ipc
+ company = "Morpheus Cyberkinetics"
+ desc = "This limb is simple and functional; no effort has been made to make it look human."
+ icon = 'icons/mob/human_races/cyberlimbs/ipc.dmi'
+ unavailable_at_chargen = 1
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/subtypes/diona.dm
similarity index 52%
rename from code/modules/organs/organ_alien.dm
rename to code/modules/organs/subtypes/diona.dm
index 70321a7fb2e..f08a5a93711 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/subtypes/diona.dm
@@ -196,189 +196,3 @@
/obj/item/organ/diona/node/removed()
return
-
-//CORTICAL BORER ORGANS.
-/obj/item/organ/borer
- name = "cortical borer"
- parent_organ = "head"
- vital = 1
-
-/obj/item/organ/borer/process()
-
- // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss.
- for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine"))
- if(owner.reagents.get_reagent_amount(chem) < 3)
- owner.reagents.add_reagent(chem, 5)
-
- // They're also super gross and ooze ichor.
- if(prob(5))
- var/mob/living/carbon/human/H = owner
- if(!istype(H))
- return
-
- var/datum/reagent/blood/B = locate(/datum/reagent/blood) in H.vessel.reagent_list
- blood_splatter(H,B,1)
- var/obj/effect/decal/cleanable/blood/splatter/goo = locate() in get_turf(owner)
- if(goo)
- goo.name = "husk ichor"
- goo.desc = "It's thick and stinks of decay."
- goo.basecolor = "#412464"
- goo.update_icon()
-
-/obj/item/organ/borer
- name = "cortical borer"
- icon = 'icons/obj/objects.dmi'
- icon_state = "borer"
- organ_tag = "brain"
- desc = "A disgusting space slug."
-
-/obj/item/organ/borer/removed(var/mob/living/user)
-
- ..()
-
- var/mob/living/simple_animal/borer/B = owner.has_brain_worms()
- if(B)
- B.leave_host()
- B.ckey = owner.ckey
-
- spawn(0)
- qdel(src)
-
-//XENOMORPH ORGANS
-/obj/item/organ/xenos/eggsac
- name = "egg sac"
- parent_organ = "groin"
-
-/obj/item/organ/xenos/plasmavessel
- name = "plasma vessel"
- parent_organ = "chest"
- var/stored_plasma = 0
- var/max_plasma = 500
-
-/obj/item/organ/xenos/plasmavessel/queen
- name = "bloated plasma vessel"
- stored_plasma = 200
- max_plasma = 500
-
-/obj/item/organ/xenos/plasmavessel/sentinel
- stored_plasma = 100
- max_plasma = 250
-
-/obj/item/organ/xenos/plasmavessel/hunter
- name = "tiny plasma vessel"
- stored_plasma = 100
- max_plasma = 150
-
-/obj/item/organ/xenos/acidgland
- name = "acid gland"
- parent_organ = "head"
-
-/obj/item/organ/xenos/hivenode
- name = "hive node"
- parent_organ = "chest"
-
-/obj/item/organ/xenos/resinspinner
- name = "resin spinner"
- parent_organ = "head"
-
-/obj/item/organ/xenos
- name = "xeno organ"
- icon = 'icons/effects/blood.dmi'
- desc = "It smells like an accident in a chemical factory."
-
-/obj/item/organ/xenos/eggsac
- name = "egg sac"
- icon_state = "xgibmid1"
- organ_tag = "egg sac"
-
-/obj/item/organ/xenos/plasmavessel
- name = "plasma vessel"
- icon_state = "xgibdown1"
- organ_tag = "plasma vessel"
-
-/obj/item/organ/xenos/acidgland
- name = "acid gland"
- icon_state = "xgibtorso"
- organ_tag = "acid gland"
-
-/obj/item/organ/xenos/hivenode
- name = "hive node"
- icon_state = "xgibmid2"
- organ_tag = "hive node"
-
-/obj/item/organ/xenos/resinspinner
- name = "hive node"
- icon_state = "xgibmid2"
- organ_tag = "resin spinner"
-
-//VOX ORGANS.
-/obj/item/organ/stack
- name = "cortical stack"
- parent_organ = "head"
- robotic = 2
- vital = 1
- var/backup_time = 0
- var/datum/mind/backup
-
-/obj/item/organ/stack/process()
- if(owner && owner.stat != 2 && !is_broken())
- backup_time = world.time
- if(owner.mind) backup = owner.mind
-
-/obj/item/organ/stack/vox
-
-/obj/item/organ/stack/vox/stack
-
-/obj/item/organ/stack
- name = "cortical stack"
- icon_state = "brain-prosthetic"
- organ_tag = "stack"
- robotic = 2
-
-/obj/item/organ/stack/vox
- name = "vox cortical stack"
-
-// Slime limbs.
-/obj/item/organ/external/chest/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/groin/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/arm/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/arm/right/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/leg/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/leg/right/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/foot/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/foot/right/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/hand/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/hand/right/slime
- cannot_break = 1
- dislocated = -1
-
-/obj/item/organ/external/head/slime
- cannot_break = 1
- dislocated = -1
diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm
new file mode 100644
index 00000000000..28c44bc41e5
--- /dev/null
+++ b/code/modules/organs/subtypes/machine.dm
@@ -0,0 +1,141 @@
+// IPC limbs.
+/obj/item/organ/external/head/ipc
+ dislocated = -1
+ can_intake_reagents = 0
+ encased = null
+/obj/item/organ/external/head/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/chest/ipc
+ dislocated = -1
+ encased = null
+/obj/item/organ/external/chest/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/groin/ipc
+ dislocated = -1
+/obj/item/organ/external/groin/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/arm/ipc
+ dislocated = -1
+/obj/item/organ/external/arm/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/arm/right/ipc
+ dislocated = -1
+/obj/item/organ/external/arm/right/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/leg/ipc
+ dislocated = -1
+/obj/item/organ/external/leg/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/leg/right/ipc
+ dislocated = -1
+/obj/item/organ/external/leg/right/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/foot/ipc
+ dislocated = -1
+/obj/item/organ/external/foot/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/foot/right/ipc
+ dislocated = -1
+/obj/item/organ/external/foot/right/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/hand/ipc
+ dislocated = -1
+/obj/item/organ/external/hand/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/external/hand/right/ipc
+ dislocated = -1
+/obj/item/organ/external/hand/right/ipc/New()
+ robotize("Morpheus Cyberkinetics")
+ ..()
+
+/obj/item/organ/cell
+ name = "microbattery"
+ desc = "A small, powerful cell for use in fully prosthetic bodies."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "scell"
+ organ_tag = "cell"
+ parent_organ = "chest"
+ vital = 1
+
+/obj/item/organ/cell/New()
+ robotize()
+ ..()
+
+/obj/item/organ/cell/replaced()
+ ..()
+ // This is very ghetto way of rebooting an IPC. TODO better way.
+ if(owner && owner.stat == DEAD)
+ owner.stat = 0
+ owner.visible_message("\The [owner] twitches visibly!")
+
+// Used for an MMI or posibrain being installed into a human.
+/obj/item/organ/mmi_holder
+ name = "brain"
+ organ_tag = "brain"
+ parent_organ = "head"
+ vital = 1
+ var/obj/item/device/mmi/stored_mmi
+
+/obj/item/organ/mmi_holder/proc/update_from_mmi()
+ if(!stored_mmi)
+ return
+ name = stored_mmi.name
+ desc = stored_mmi.desc
+ icon = stored_mmi.icon
+ icon_state = stored_mmi.icon_state
+
+/obj/item/organ/mmi_holder/removed(var/mob/living/user)
+
+ if(stored_mmi)
+ stored_mmi.loc = get_turf(src)
+ if(owner.mind)
+ owner.mind.transfer_to(stored_mmi.brainmob)
+ ..()
+
+ var/mob/living/holder_mob = loc
+ if(istype(holder_mob))
+ holder_mob.drop_from_inventory(src)
+ qdel(src)
+
+/obj/item/organ/mmi_holder/New()
+ ..()
+ // This is very ghetto way of rebooting an IPC. TODO better way.
+ spawn(1)
+ if(owner && owner.stat == DEAD)
+ owner.stat = 0
+ owner.visible_message("\The [owner] twitches visibly!")
+
+/obj/item/organ/mmi_holder/posibrain/New()
+ robotize()
+ stored_mmi = new /obj/item/device/mmi/digital/posibrain(src)
+ ..()
+ spawn(1)
+ if(owner)
+ stored_mmi.name = "positronic brain ([owner.name])"
+ stored_mmi.brainmob.real_name = owner.name
+ stored_mmi.brainmob.name = stored_mmi.brainmob.real_name
+ stored_mmi.icon_state = "posibrain-occupied"
+ update_from_mmi()
+ else
+ stored_mmi.loc = get_turf(src)
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm
new file mode 100644
index 00000000000..3a7e18a9dc8
--- /dev/null
+++ b/code/modules/organs/subtypes/standard.dm
@@ -0,0 +1,163 @@
+/****************************************************
+ ORGAN DEFINES
+****************************************************/
+
+/obj/item/organ/external/chest
+ name = "upper body"
+ limb_name = "chest"
+ icon_name = "torso"
+ health = 100
+ min_broken_damage = 35
+ body_part = UPPER_TORSO
+ vital = 1
+ amputation_point = "spine"
+ joint = "neck"
+ dislocated = -1
+ gendered_icon = 1
+ cannot_amputate = 1
+ parent_organ = null
+ encased = "ribcage"
+
+/obj/item/organ/external/groin
+ name = "lower body"
+ limb_name = "groin"
+ icon_name = "groin"
+ health = 100
+ min_broken_damage = 35
+ body_part = LOWER_TORSO
+ vital = 1
+ parent_organ = "chest"
+ amputation_point = "lumbar"
+ joint = "hip"
+ dislocated = -1
+ gendered_icon = 1
+
+/obj/item/organ/external/arm
+ limb_name = "l_arm"
+ name = "left arm"
+ icon_name = "l_arm"
+ health = 50
+ min_broken_damage = 30
+ body_part = ARM_LEFT
+ parent_organ = "chest"
+ joint = "left elbow"
+ amputation_point = "left shoulder"
+ can_grasp = 1
+
+/obj/item/organ/external/arm/right
+ limb_name = "r_arm"
+ name = "right arm"
+ icon_name = "r_arm"
+ body_part = ARM_RIGHT
+ joint = "right elbow"
+ amputation_point = "right shoulder"
+
+/obj/item/organ/external/leg
+ limb_name = "l_leg"
+ name = "left leg"
+ icon_name = "l_leg"
+ health = 50
+ min_broken_damage = 30
+ body_part = LEG_LEFT
+ icon_position = LEFT
+ parent_organ = "groin"
+ joint = "left knee"
+ amputation_point = "left hip"
+ can_stand = 1
+
+/obj/item/organ/external/leg/right
+ limb_name = "r_leg"
+ name = "right leg"
+ icon_name = "r_leg"
+ body_part = LEG_RIGHT
+ icon_position = RIGHT
+ joint = "right knee"
+ amputation_point = "right hip"
+
+/obj/item/organ/external/foot
+ limb_name = "l_foot"
+ name = "left foot"
+ icon_name = "l_foot"
+ health = 30
+ min_broken_damage = 15
+ body_part = FOOT_LEFT
+ icon_position = LEFT
+ parent_organ = "l_leg"
+ joint = "left ankle"
+ amputation_point = "left ankle"
+ can_stand = 1
+
+/obj/item/organ/external/foot/removed()
+ if(owner) owner.u_equip(owner.shoes)
+ ..()
+
+/obj/item/organ/external/foot/right
+ limb_name = "r_foot"
+ name = "right foot"
+ icon_name = "r_foot"
+ body_part = FOOT_RIGHT
+ icon_position = RIGHT
+ parent_organ = "r_leg"
+ joint = "right ankle"
+ amputation_point = "right ankle"
+
+/obj/item/organ/external/hand
+ limb_name = "l_hand"
+ name = "left hand"
+ icon_name = "l_hand"
+ health = 30
+ min_broken_damage = 15
+ body_part = HAND_LEFT
+ parent_organ = "l_arm"
+ joint = "left wrist"
+ amputation_point = "left wrist"
+ can_grasp = 1
+
+/obj/item/organ/external/hand/removed()
+ owner.u_equip(owner.gloves)
+ ..()
+
+/obj/item/organ/external/hand/right
+ limb_name = "r_hand"
+ name = "right hand"
+ icon_name = "r_hand"
+ body_part = HAND_RIGHT
+ parent_organ = "r_arm"
+ joint = "right wrist"
+ amputation_point = "right wrist"
+
+/obj/item/organ/external/head
+ limb_name = "head"
+ icon_name = "head"
+ name = "head"
+ health = 75
+ min_broken_damage = 35
+ body_part = HEAD
+ vital = 1
+ parent_organ = "chest"
+ joint = "jaw"
+ amputation_point = "neck"
+ gendered_icon = 1
+ encased = "skull"
+ var/can_intake_reagents = 1
+
+/obj/item/organ/external/head/removed()
+ if(owner)
+ name = "[owner.real_name]'s head"
+ owner.u_equip(owner.glasses)
+ owner.u_equip(owner.head)
+ owner.u_equip(owner.l_ear)
+ owner.u_equip(owner.r_ear)
+ owner.u_equip(owner.wear_mask)
+ spawn(1)
+ owner.update_hair()
+ ..()
+
+/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
+ ..(brute, burn, sharp, edge, used_weapon, forbidden_limbs)
+ if (!disfigured)
+ if (brute_dam > 40)
+ if (prob(50))
+ disfigure("brute")
+ if (burn_dam > 40)
+ disfigure("burn")
diff --git a/code/modules/organs/subtypes/unbreakable.dm b/code/modules/organs/subtypes/unbreakable.dm
new file mode 100644
index 00000000000..137249e7473
--- /dev/null
+++ b/code/modules/organs/subtypes/unbreakable.dm
@@ -0,0 +1,44 @@
+// Slime limbs.
+/obj/item/organ/external/chest/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/groin/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/arm/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/arm/right/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/leg/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/leg/right/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/foot/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/foot/right/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/hand/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/hand/right/unbreakable
+ cannot_break = 1
+ dislocated = -1
+
+/obj/item/organ/external/head/unbreakable
+ cannot_break = 1
+ dislocated = -1
diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm
new file mode 100644
index 00000000000..0b1233085fd
--- /dev/null
+++ b/code/modules/organs/subtypes/xenos.dm
@@ -0,0 +1,52 @@
+//XENOMORPH ORGANS
+/obj/item/organ/xenos
+ name = "xeno organ"
+ icon = 'icons/effects/blood.dmi'
+ desc = "It smells like an accident in a chemical factory."
+
+/obj/item/organ/xenos/eggsac
+ name = "egg sac"
+ parent_organ = "groin"
+ icon_state = "xgibmid1"
+ organ_tag = "egg sac"
+
+/obj/item/organ/xenos/plasmavessel
+ name = "plasma vessel"
+ parent_organ = "chest"
+ icon_state = "xgibdown1"
+ organ_tag = "plasma vessel"
+ var/stored_plasma = 0
+ var/max_plasma = 500
+
+/obj/item/organ/xenos/plasmavessel/queen
+ name = "bloated plasma vessel"
+ stored_plasma = 200
+ max_plasma = 500
+
+/obj/item/organ/xenos/plasmavessel/sentinel
+ stored_plasma = 100
+ max_plasma = 250
+
+/obj/item/organ/xenos/plasmavessel/hunter
+ name = "tiny plasma vessel"
+ stored_plasma = 100
+ max_plasma = 150
+
+/obj/item/organ/xenos/acidgland
+ name = "acid gland"
+ parent_organ = "head"
+ icon_state = "xgibtorso"
+ organ_tag = "acid gland"
+
+/obj/item/organ/xenos/hivenode
+ name = "hive node"
+ parent_organ = "chest"
+ icon_state = "xgibmid2"
+ organ_tag = "hive node"
+
+/obj/item/organ/xenos/resinspinner
+ name = "resin spinner"
+ parent_organ = "head"
+ icon_state = "xgibmid2"
+ organ_tag = "resin spinner"
+
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index f21db9327d4..8c0144710ec 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -664,34 +664,7 @@
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
- if(H.species.flags & IS_SYNTHETIC && H.a_intent == I_GRAB)
- if(emagged || stat & BROKEN)
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- H << "\red The APC power currents surge eratically, damaging your chassis!"
- H.adjustFireLoss(10,0)
- else if(src.cell && src.cell.charge > 0)
- if(H.nutrition < 450)
-
- if(src.cell.charge >= 500)
- H.nutrition += 50
- src.cell.charge -= 500
- else
- H.nutrition += src.cell.charge/10
- src.cell.charge = 0
-
- user << "\blue You slot your fingers into the APC interface and siphon off some of the stored charge for your own use."
- if(src.cell.charge < 0) src.cell.charge = 0
- if(H.nutrition > 500) H.nutrition = 500
- src.charging = 1
-
- else
- user << "\blue You are already fully charged."
- else
- user << "There is no charge to draw from that APC."
- return
- else if(H.species.can_shred(H))
+ if(H.species.can_shred(H))
user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!")
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index e5be56b9440..d883054b1bd 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -519,14 +519,12 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
return ..()
- if(H.species.flags & IS_SYNTHETIC)
- if(M == user)
- user << "\red You can't repair damage to your own body - it's against OH&S."
- return
-
if(S.burn_dam > 0 && use(1))
- S.heal_damage(0,15,0,1)
- user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].")
+ if(S.burn_dam < ROBOLIMB_SELF_REPAIR_CAP)
+ S.heal_damage(0,15,0,1)
+ user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].")
+ else
+ user << "\red The damage is far too severe to patch over externally."
return
else
user << "Nothing to fix!"
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 0e0da75e2a6..2d8ece18c12 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -1,11 +1,11 @@
/datum/reagent
var/name = "Reagent"
var/id = "reagent"
- var/description = "A non-descript chemical."
+ var/description = "A non-descript chemical."
var/datum/reagents/holder = null
var/reagent_state = SOLID
var/list/data = null
- var/volume = 0
+ var/volume = 0
var/metabolism = REM // This would be 0.2 normally
var/ingest_met = 0
var/touch_met = 0
@@ -13,11 +13,11 @@
var/max_dose = 0
var/overdose = 0
var/scannable = 0 // Shows up on health analyzers.
- var/affects_dead = 0
+ var/affects_dead = 0
var/glass_icon_state = null
var/glass_name = null
var/glass_desc = null
- var/glass_center_of_mass = null
+ var/glass_center_of_mass = null
var/color = "#000000"
var/color_weight = 1
@@ -86,11 +86,11 @@
return data.Copy()
else if(data)
return data
- return null
+ return null
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
..()
- holder = null
+ holder = null
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
@@ -108,4 +108,4 @@
id = "woodpulp"
description = "A mass of wood fibers."
reagent_state = LIQUID
- color = "#B97A57"
+ color = "#B97A57"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
index cafd3aed25b..c7afddee391 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -57,6 +57,8 @@
M.adjustToxLoss(removed)
/datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien == IS_MACHINE)
+ return
if(data && data["viruses"])
for(var/datum/disease/D in data["viruses"])
if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS)
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
index 97db6ceab5e..2f9cc0f548e 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
@@ -226,11 +226,11 @@
M.adjustToxLoss(0.5 * removed)
/datum/reagent/capsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
- if(alien == IS_DIONA)
+ if(alien == IS_DIONA || alien == IS_MACHINE)
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species && (H.species.flags & (NO_PAIN | IS_SYNTHETIC)))
+ if(H.species && (H.species.flags & (NO_PAIN)))
return
if(dose < 5 && (dose == metabolism || prob(5)))
M << "Your insides feel uncomfortably hot!"
@@ -307,7 +307,7 @@
/datum/reagent/condensedcapsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species && (H.species.flags & (NO_PAIN | IS_SYNTHETIC)))
+ if(H.species && (H.species.flags & (NO_PAIN)))
return
if(dose == metabolism)
M << "You feel like your insides are burning!"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index b7396713121..9f8e05a20b6 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -229,6 +229,9 @@
affect_blood(M, alien, removed)
/datum/reagent/mutagen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && (H.species.flags & NO_SCAN))
+ return
if(M.dna)
if(prob(removed * 0.1)) // Approx. one mutation per 10 injected/20 ingested/30 touching units
randmuti(M)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 2d0a1469b58..17de69ae346 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -25,9 +25,9 @@
/obj/item/weapon/reagent_containers/attack_self(mob/user as mob)
return
-/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone)
+/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone)
if(can_operate(M))//Checks if mob is lying down on table for surgery
- if(do_surgery(M, user, src))
+ if(do_surgery(M, user, src))
return
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag)
@@ -98,10 +98,9 @@
if(target == user)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
- if(H.species.flags & IS_SYNTHETIC)
- H << "You have a monitor for a head, where do you think you're going to put that?"
- return 1
-
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? You don't have a mouth!"
+ return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "\The [blocked] is in the way!"
@@ -114,10 +113,9 @@
else
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
- if(H.species.flags & IS_SYNTHETIC)
- H << "They have a monitor for a head, where do you think you're going to put that?"
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!"
return
-
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "\The [blocked] is in the way!"
@@ -153,4 +151,4 @@
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "You transfer [trans] units of the solution to [target]."
- return 1
+ return 1
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 985ed3d9d27..b57830e1d62 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -65,6 +65,16 @@
if (!istype(M))
return
+ var/mob/living/carbon/human/H = M
+ if(istype(H))
+ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ user << "\The [H] is missing that limb!"
+ return
+ else if(affected.status & ORGAN_ROBOT)
+ user << "You cannot inject a robotic limb."
+ return
+
if (R.total_volume && M.can_inject(user, 1))
user << "You inject [M] with the injector."
M << "You feel a tiny prick!"
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index a63fbdd46bc..47240eeb222 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -45,10 +45,9 @@
if(M == user) //If you're eating it yourself
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- H << "You have a monitor for a head, where do you think you're going to put that?"
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? You don't have a mouth!"
return
-
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "\The [blocked] is in the way!"
@@ -68,10 +67,9 @@
else
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- user << "They have a monitor for a head, where do you think you're going to put that?"
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!"
return
-
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "\The [blocked] is in the way!"
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index c5153510d7b..f39d7167fab 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -25,6 +25,17 @@
return
if (!istype(M))
return
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H))
+ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ user << "\The [H] is missing that limb!"
+ return
+ else if(affected.status & ORGAN_ROBOT)
+ user << "You cannot inject a robotic limb."
+ return
+
user << "You inject [M] with [src]."
M << "You feel a tiny prick!"
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index bb405828ee3..0891468cd10 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -21,10 +21,9 @@
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- H << "You have a monitor for a head, where do you think you're going to put that?"
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? You don't have a mouth!"
return
-
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "\The [blocked] is in the way!"
@@ -40,12 +39,10 @@
else if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species.flags & IS_SYNTHETIC)
- H << "They have a monitor for a head, where do you think you're going to put that?"
+ if(!H.check_has_mouth())
+ user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!"
return
-
var/obj/item/blocked = H.check_mouth_coverage()
-
if(blocked)
user << "\The [blocked] is in the way!"
return
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index c7f869802bb..bdc17b298c4 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -142,13 +142,21 @@
user << "[target] is full."
return
+ var/mob/living/carbon/human/H = target
+ if(istype(H))
+ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ user << "\The [H] is missing that limb!"
+ return
+ else if(affected.status & ORGAN_ROBOT)
+ user << "You cannot inject a robotic limb."
+ return
+
if(ismob(target) && target != user)
var/injtime = time //Injecting through a hardsuit takes longer due to needing to find a port.
- if(istype(target, /mob/living/carbon/human))
-
- var/mob/living/carbon/human/H = target
+ if(istype(H))
if(H.wear_suit)
if(istype(H.wear_suit, /obj/item/clothing/suit/space))
injtime = injtime * 2
diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm
index bbeb1603b7e..3368c8344d0 100644
--- a/code/modules/supermatter/supermatter.dm
+++ b/code/modules/supermatter/supermatter.dm
@@ -130,7 +130,7 @@
/obj/machinery/power/supermatter/proc/announce_warning()
var/integrity = get_integrity()
var/alert_msg = " Integrity at [integrity]%"
-
+
if(damage > emergency_point)
alert_msg = emergency_alert + alert_msg
lastwarning = world.timeofday - WARNING_DELAY * 4
@@ -153,7 +153,7 @@
else if(safe_warned && public_alert)
radio.autosay(alert_msg, "Supermatter Monitor")
public_alert = 0
-
+
/obj/machinery/power/supermatter/process()
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index b2ccbb10032..25addbd40a4 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -18,7 +18,7 @@
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.open >= 2 && affected.stage == 0
+ return affected && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 0
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -52,7 +52,7 @@
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.name != "head" && affected.open >= 2 && affected.stage == 1
+ return affected && affected.name != "head" && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -91,7 +91,7 @@
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.name == "head" && affected.open >= 2 && affected.stage == 1
+ return affected && affected.name == "head" && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \
@@ -127,7 +127,7 @@
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.open >= 2 && affected.stage == 2
+ return affected && affected.open >= 2 && !(affected.status & ORGAN_ROBOT) && affected.stage == 2
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm
deleted file mode 100644
index 6935b09d244..00000000000
--- a/code/modules/surgery/brainrepair.dm
+++ /dev/null
@@ -1,70 +0,0 @@
-//////////////////////////////////////////////////////////////////
-// BRAIN DAMAGE FIXING //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/brain/bone_chips
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/material/kitchen/utensil/fork = 20
- )
-
- priority = 3
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- return (sponge && sponge.damage > 0 && sponge.damage <= 20) && affected.open == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts taking bone chips out of [target]'s brain with \the [tool].", \
- "You start taking bone chips out of [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] takes out all the bone chips in [target]'s brain with \the [tool].", \
- "\blue You take out all the bone chips in [target]'s brain with \the [tool].")
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- if (sponge)
- sponge.damage = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \
- "\red Your hand slips, jabbing \the [tool] in [target]'s brain!")
- target.apply_damage(30, BRUTE, "head", 1, sharp=1)
-
-/datum/surgery_step/brain/hematoma
- allowed_tools = list(
- /obj/item/weapon/FixOVein = 100, \
- /obj/item/stack/cable_coil = 75
- )
-
- priority = 3
- min_duration = 90
- max_duration = 110
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- return (sponge && sponge.damage > 20) && affected.open == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending hematoma in [target]'s brain with \the [tool].", \
- "You start mending hematoma in [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \
- "\blue You mend hematoma in [target]'s brain with \the [tool].")
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- if (sponge)
- sponge.damage = 20
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \
- "\red Your hand slips, bruising [target]'s brain with \the [tool]!")
- target.apply_damage(20, BRUTE, "head", 1, sharp=1)
\ No newline at end of file
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index 8e1a5163842..1744cec3d7e 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -12,7 +12,7 @@
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.encased && affected.open >= 2
+ return affected && !(affected.status & ORGAN_ROBOT) && affected.encased && affected.open >= 2
/datum/surgery_step/open_encased/saw
diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm
deleted file mode 100644
index 7b69fea7ff6..00000000000
--- a/code/modules/surgery/eye.dm
+++ /dev/null
@@ -1,147 +0,0 @@
-//Procedures in this file: Eye mending surgery
-//////////////////////////////////////////////////////////////////
-// EYE SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/eye
- priority = 2
- can_infect = 1
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!hasorgans(target))
- return 0
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if (!affected)
- return 0
-
- var/obj/item/organ/eyes = target.internal_organs_by_name["eyes"]
-
- return target_zone == "eyes" && eyes
-
-/datum/surgery_step/eye/cut_open
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/material/knife = 75, \
- /obj/item/weapon/material/shard = 50, \
- )
-
- min_duration = 90
- max_duration = 110
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..()
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts to separate the corneas on [target]'s eyes with \the [tool].", \
- "You start to separate the corneas on [target]'s eyes with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has separated the corneas on [target]'s eyes with \the [tool]." , \
- "\blue You have separated the corneas on [target]'s eyes with \the [tool].",)
- target.op_stage.eyes = 1
- target.blinded += 1.5
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, slicing [target]'s eyes wth \the [tool]!" , \
- "\red Your hand slips, slicing [target]'s eyes wth \the [tool]!" )
- affected.createwound(CUT, 10)
- eyes.take_damage(5, 0)
-
-/datum/surgery_step/eye/lift_eyes
- allowed_tools = list(
- /obj/item/weapon/retractor = 100, \
- /obj/item/weapon/material/kitchen/utensil/fork = 50
- )
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.eyes == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts lifting corneas from [target]'s eyes with \the [tool].", \
- "You start lifting corneas from [target]'s eyes with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has lifted the corneas from [target]'s eyes from with \the [tool]." , \
- "\blue You has lifted the corneas from [target]'s eyes from with \the [tool]." )
- target.op_stage.eyes = 2
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging [target]'s eyes with \the [tool]!", \
- "\red Your hand slips, damaging [target]'s eyes with \the [tool]!")
- target.apply_damage(10, BRUTE, affected)
- eyes.take_damage(5, 0)
-
-/datum/surgery_step/eye/mend_eyes
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/stack/cable_coil = 75, \
- /obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity.
- )
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.eyes == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending the nerves and lenses in [target]'s eyes with \the [tool].", \
- "You start mending the nerves and lenses in [target]'s eyes with the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends the nerves and lenses in [target]'s with \the [tool]." , \
- "\blue You mend the nerves and lenses in [target]'s with \the [tool].")
- target.op_stage.eyes = 3
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, stabbing \the [tool] into [target]'s eye!", \
- "\red Your hand slips, stabbing \the [tool] into [target]'s eye!")
- target.apply_damage(10, BRUTE, affected, sharp=1)
- eyes.take_damage(5, 0)
-
-/datum/surgery_step/eye/cauterize
- allowed_tools = list(
- /obj/item/weapon/cautery = 100, \
- /obj/item/clothing/mask/smokable/cigarette = 75, \
- /obj/item/weapon/flame/lighter = 50, \
- /obj/item/weapon/weldingtool = 25
- )
-
- min_duration = 70
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..()
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] is beginning to cauterize the incision around [target]'s eyes with \the [tool]." , \
- "You are beginning to cauterize the incision around [target]'s eyes with \the [tool].")
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- user.visible_message("\blue [user] cauterizes the incision around [target]'s eyes with \the [tool].", \
- "\blue You cauterize the incision around [target]'s eyes with \the [tool].")
- if (target.op_stage.eyes == 3)
- target.disabilities &= ~NEARSIGHTED
- target.sdisabilities &= ~BLIND
- eyes.damage = 0
- target.op_stage.eyes = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, searing [target]'s eyes with \the [tool]!", \
- "\red Your hand slips, searing [target]'s eyes with \the [tool]!")
- target.apply_damage(5, BURN, affected)
- eyes.take_damage(5, 0)
\ No newline at end of file
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index 0a42f7c1374..7272ecf49e0 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -10,7 +10,7 @@
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if (!affected)
+ if (!affected || (affected.status & ORGAN_ROBOT))
return 0
return target_zone == "mouth"
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index c1e51d9c4df..20bf10bd002 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -17,8 +17,6 @@
return 0
if (affected.status & ORGAN_DESTROYED)
return 0
- if (target_zone == "head" && target.species && (target.species.flags & IS_SYNTHETIC))
- return 1
if (affected.status & ORGAN_ROBOT)
return 0
return 1
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index 95980d52521..62cf65b2ce9 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -32,6 +32,12 @@
return "abdominal"
return ""
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \
+ "\red Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!")
+ affected.createwound(CUT, 20)
+
/datum/surgery_step/cavity/make_space
allowed_tools = list(
/obj/item/weapon/surgicaldrill = 100, \
@@ -60,12 +66,6 @@
user.visible_message("\blue [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
"\blue You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20)
-
/datum/surgery_step/cavity/close_space
priority = 2
allowed_tools = list(
@@ -96,12 +96,6 @@
user.visible_message("\blue [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \
"\blue You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." )
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20)
-
/datum/surgery_step/cavity/place_item
priority = 0
allowed_tools = list(/obj/item = 100)
@@ -126,7 +120,7 @@
user.visible_message("\blue [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
"\blue You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." )
- if (tool.w_class > get_max_wclass(affected)/2 && prob(50))
+ if (tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT))
user << "\red You tear some blood vessels trying to fit such a big object in this cavity."
var/datum/wound/internal_bleeding/I = new (10)
affected.wounds += I
@@ -136,12 +130,6 @@
tool.loc = target
affected.cavity = 0
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20)
-
//////////////////////////////////////////////////////////////////
// IMPLANT/ITEM REMOVAL SURGERY //
//////////////////////////////////////////////////////////////////
@@ -162,9 +150,9 @@
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.name] with \the [tool].", \
- "You start poking around inside the incision on [target]'s [affected.name] with \the [tool]" )
- target.custom_pain("The pain in your chest is living hell!",1)
+ user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \
+ "You start poking around inside [target]'s [affected.name] with \the [tool]" )
+ target.custom_pain("The pain in your [affected.name] is living hell!",1)
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -209,8 +197,8 @@
user.visible_message("\blue [user] removes \the [tool] from [target]'s [affected.name].", \
"\blue There's something inside [target]'s [affected.name], but you just missed it this time." )
else if (affected.hidden)
- user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \
- "\blue You take something out of incision on [target]'s [affected.name]s with \the [tool]." )
+ user.visible_message("\blue [user] takes something out of [target]'s [affected.name] with \the [tool].", \
+ "\blue You take something out of [target]'s [affected.name]s with \the [tool]." )
affected.hidden.loc = get_turf(target)
if(!affected.hidden.blood_DNA)
affected.hidden.blood_DNA = list()
@@ -223,10 +211,8 @@
"\blue You could not find anything inside [target]'s [affected.name]." )
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ ..()
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20)
if (affected.implants.len)
var/fail_prob = 10
fail_prob += 100 - tool_quality(tool)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index a97184f35cb..d352c4aed48 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -138,75 +138,6 @@
if(I && I.damage > 0)
I.take_damage(dam_amt,0)
-/datum/surgery_step/internal/fix_organ_robotic //For artificial organs
- allowed_tools = list(
- /obj/item/stack/nanopaste = 100, \
- /obj/item/weapon/bonegel = 30, \
- /obj/item/weapon/screwdriver = 70, \
- )
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return
- var/is_organ_damaged = 0
- for(var/obj/item/organ/I in affected.internal_organs)
- if(I.damage > 0 && I.robotic >= 2)
- is_organ_damaged = 1
- break
- return ..() && is_organ_damaged
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
-
- for(var/obj/item/organ/I in affected.internal_organs)
- if(I && I.damage > 0)
- if(I.robotic >= 2)
- user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
- "You start mending the damage to [target]'s [I.name]'s mechanisms." )
-
- target.custom_pain("The pain in your [affected.name] is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
-
- for(var/obj/item/organ/I in affected.internal_organs)
-
- if(I && I.damage > 0)
- if(I.robotic >= 2)
- user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \
- "\blue You repair [target]'s [I.name] with [tool]." )
- I.damage = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
-
- user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!")
-
- target.adjustToxLoss(5)
- affected.createwound(CUT, 5)
-
- for(var/obj/item/organ/I in affected.internal_organs)
- if(I)
- I.take_damage(rand(3,5),0)
-
-
/datum/surgery_step/internal/detatch_organ
allowed_tools = list(
@@ -223,12 +154,17 @@
if (!..())
return 0
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+
+ if(!(affected && !(affected.status & ORGAN_ROBOT)))
+ return 0
+
target.op_stage.current_organ = null
var/list/attached_organs = list()
for(var/organ in target.internal_organs_by_name)
var/obj/item/organ/I = target.internal_organs_by_name[organ]
- if(I && !I.status && I.parent_organ == target_zone)
+ if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone)
attached_organs |= organ
var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs
@@ -283,7 +219,7 @@
var/list/removable_organs = list()
for(var/organ in target.internal_organs_by_name)
var/obj/item/organ/I = target.internal_organs_by_name[organ]
- if(I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone)
+ if((I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone)
removable_organs |= organ
var/organ_to_remove = input(user, "Which organ do you want to remove?") as null|anything in removable_organs
@@ -312,8 +248,8 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \
- "\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!")
+ user.visible_message("\red [user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \
+ "\red Your hand slips, damaging [target]'s [affected.name] with \the [tool]!")
affected.createwound(BRUISE, 20)
/datum/surgery_step/internal/replace_organ
@@ -335,6 +271,10 @@
if(!istype(O))
return 0
+ if((affected.status & ORGAN_ROBOT) && !(O.status & ORGAN_ROBOT))
+ user << "You cannot install a naked organ into a robotic body."
+ return 2
+
if(!target.species)
user << "\red You have no idea what species this person is. Report this on the bug tracker."
return 2
@@ -410,7 +350,7 @@
var/list/removable_organs = list()
for(var/organ in target.internal_organs_by_name)
var/obj/item/organ/I = target.internal_organs_by_name[organ]
- if(I && I.status & ORGAN_CUT_AWAY && I.parent_organ == target_zone)
+ if(I && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone)
removable_organs |= organ
var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 50e6c3bcfb9..ba9334d933a 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -186,7 +186,7 @@
return 0
if(istype(tool,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/welder = tool
- if(!welder.isOn())
+ if(!welder.isOn() || !welder.remove_fuel(1,user))
return 0
return (target_zone == "chest") && istype(target.back, /obj/item/weapon/rig) && !(target.back.canremove)
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
new file mode 100644
index 00000000000..11babd42e42
--- /dev/null
+++ b/code/modules/surgery/robotics.dm
@@ -0,0 +1,421 @@
+//Procedures in this file: Gneric surgery steps
+//////////////////////////////////////////////////////////////////
+// COMMON STEPS //
+//////////////////////////////////////////////////////////////////
+
+/datum/surgery_step/robotics/
+ can_infect = 0
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (isslime(target))
+ return 0
+ if (target_zone == "eyes") //there are specific steps for eye surgery
+ return 0
+ if (!hasorgans(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if (affected == null)
+ return 0
+ if (affected.status & ORGAN_DESTROYED)
+ return 0
+ if (!(affected.status & ORGAN_ROBOT))
+ return 0
+ return 1
+
+/datum/surgery_step/robotics/unscrew_hatch
+ allowed_tools = list(
+ /obj/item/weapon/screwdriver = 100,
+ /obj/item/weapon/coin = 50,
+ /obj/item/weapon/material/kitchen/utensil/knife = 50
+ )
+
+ min_duration = 90
+ max_duration = 110
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(..())
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ return affected && affected.open == 0 && target_zone != "mouth"
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].", \
+ "You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \
+ "\blue You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",)
+ affected.open = 1
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \
+ "\red Your [tool] slips, failing to unscrew [target]'s [affected.name].")
+
+/datum/surgery_step/robotics/open_hatch
+ allowed_tools = list(
+ /obj/item/weapon/retractor = 100,
+ /obj/item/weapon/crowbar = 100,
+ /obj/item/weapon/material/kitchen/utensil = 50
+ )
+
+ min_duration = 30
+ max_duration = 40
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(..())
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ return affected && affected.open == 1
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].",
+ "You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] open the maintenance hatch on [target]'s [affected.name] with \the [tool].", \
+ "\blue You open the maintenance hatch on [target]'s [affected.name] with \the [tool]." )
+ affected.open = 2
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].",
+ "\red Your [tool] slips, failing to open the hatch on [target]'s [affected.name].")
+
+/datum/surgery_step/robotics/close_hatch
+ allowed_tools = list(
+ /obj/item/weapon/retractor = 100,
+ /obj/item/weapon/crowbar = 100,
+ /obj/item/weapon/material/kitchen/utensil = 50
+ )
+
+ min_duration = 70
+ max_duration = 100
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(..())
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ return affected && affected.open && target_zone != "mouth"
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \
+ "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \
+ "\blue You close and secure the hatch on [target]'s [affected.name] with \the [tool].")
+ affected.open = 0
+ affected.germ_level = 0
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].",
+ "\red Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")
+
+/datum/surgery_step/robotics/repair_brute
+ allowed_tools = list(
+ /obj/item/weapon/weldingtool = 100,
+ /obj/item/weapon/pickaxe/plasmacutter = 50
+ )
+
+ min_duration = 50
+ max_duration = 60
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(..())
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(istype(tool,/obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/welder = tool
+ if(!welder.isOn() || !welder.remove_fuel(1,user))
+ return 0
+ return affected && affected.open && affected.brute_dam > 0 && target_zone != "mouth"
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \
+ "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \
+ "\blue You finish patching damage to [target]'s [affected.name] with \the [tool].")
+ affected.heal_damage(rand(30,50),0)
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].",
+ "\red Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].")
+ target.apply_damage(rand(5,10), BURN, affected)
+
+/datum/surgery_step/robotics/repair_burn
+ allowed_tools = list(
+ /obj/item/stack/cable_coil = 100
+ )
+
+ min_duration = 50
+ max_duration = 60
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(..())
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ return affected && affected.open && affected.burn_dam > 0 && target_zone != "mouth"
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \
+ "You begin to splice new cabling into [target]'s [affected.name].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] finishes splicing cable into [target]'s [affected.name].", \
+ "\blue You finishes splicing new cable into [target]'s [affected.name].")
+ affected.heal_damage(0,rand(30,50))
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user] causes a short circuit in [target]'s [affected.name]!",
+ "\red You cause a short circuit in [target]'s [affected.name]!")
+ target.apply_damage(rand(5,10), BURN, affected)
+
+/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs
+ allowed_tools = list(
+ /obj/item/stack/nanopaste = 100, \
+ /obj/item/weapon/bonegel = 30, \
+ /obj/item/weapon/screwdriver = 70, \
+ )
+
+ min_duration = 70
+ max_duration = 90
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ if (!hasorgans(target))
+ return
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(!affected) return
+ var/is_organ_damaged = 0
+ for(var/obj/item/organ/I in affected.internal_organs)
+ if(I.damage > 0 && I.robotic >= 2)
+ is_organ_damaged = 1
+ break
+ return affected.open == 2 && is_organ_damaged
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ if (!hasorgans(target))
+ return
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+
+ for(var/obj/item/organ/I in affected.internal_organs)
+ if(I && I.damage > 0)
+ if(I.robotic >= 2)
+ user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
+ "You start mending the damage to [target]'s [I.name]'s mechanisms." )
+
+ target.custom_pain("The pain in your [affected.name] is living hell!",1)
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ if (!hasorgans(target))
+ return
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+
+ for(var/obj/item/organ/I in affected.internal_organs)
+
+ if(I && I.damage > 0)
+ if(I.robotic >= 2)
+ user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \
+ "\blue You repair [target]'s [I.name] with [tool]." )
+ I.damage = 0
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ if (!hasorgans(target))
+ return
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+
+ user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \
+ "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!")
+
+ target.adjustToxLoss(5)
+ affected.createwound(CUT, 5)
+
+ for(var/obj/item/organ/I in affected.internal_organs)
+ if(I)
+ I.take_damage(rand(3,5),0)
+
+/datum/surgery_step/robotics/detatch_organ_robotic
+
+ allowed_tools = list(
+ /obj/item/device/multitool = 100
+ )
+
+ min_duration = 90
+ max_duration = 110
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(!(affected && (affected.status & ORGAN_ROBOT)))
+ return 0
+ if(affected.open != 2)
+ return 0
+
+ target.op_stage.current_organ = null
+
+ var/list/attached_organs = list()
+ for(var/organ in target.internal_organs_by_name)
+ var/obj/item/organ/I = target.internal_organs_by_name[organ]
+ if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone)
+ attached_organs |= organ
+
+ var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs
+ if(!organ_to_remove)
+ return 0
+
+ target.op_stage.current_organ = organ_to_remove
+
+ return ..() && organ_to_remove
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("[user] starts to decouple [target]'s [target.op_stage.current_organ] with \the [tool].", \
+ "You start to decouple [target]'s [target.op_stage.current_organ] with \the [tool]." )
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("\blue [user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \
+ "\blue You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].")
+
+ var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
+ if(I && istype(I))
+ I.status |= ORGAN_CUT_AWAY
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \
+ "\red Your hand slips, disconnecting \the [tool].")
+
+/datum/surgery_step/robotics/attach_organ_robotic
+ allowed_tools = list(
+ /obj/item/weapon/screwdriver = 100,
+ )
+
+ min_duration = 100
+ max_duration = 120
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(!(affected && (affected.status & ORGAN_ROBOT)))
+ return 0
+ if(affected.open != 2)
+ return 0
+
+ target.op_stage.current_organ = null
+
+ var/list/removable_organs = list()
+ for(var/organ in target.internal_organs_by_name)
+ var/obj/item/organ/I = target.internal_organs_by_name[organ]
+ if(I && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone)
+ removable_organs |= organ
+
+ var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs
+ if(!organ_to_replace)
+ return 0
+
+ target.op_stage.current_organ = organ_to_replace
+ return ..()
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \
+ "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \
+ "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].")
+
+ var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
+ if(I && istype(I))
+ I.status &= ~ORGAN_CUT_AWAY
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \
+ "\red Your hand slips, disconnecting \the [tool].")
+
+/datum/surgery_step/robotics/install_mmi
+ allowed_tools = list(
+ /obj/item/device/mmi = 100
+ )
+
+ min_duration = 60
+ max_duration = 80
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+
+ if(target_zone != "head")
+ return
+
+ var/obj/item/device/mmi/M = tool
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(!(affected && affected.open == 2))
+ return 0
+
+ if(!istype(M))
+ return 0
+
+ if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD)
+ user << "That brain is not usable."
+ return 2
+
+ if(!(affected.status & ORGAN_ROBOT))
+ user << "You cannot install a computer brain into a meat skull."
+ return 2
+
+ if(!target.species)
+ user << "You have no idea what species this person is. Report this on the bug tracker."
+ return 2
+
+ if(!target.species.has_organ["brain"])
+ user << "You're pretty sure [target.species.name_plural] don't normally have a brain."
+ return 2
+
+ if(!isnull(target.internal_organs["brain"]))
+ user << "Your subject already has a brain."
+ return 2
+
+ return 1
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \
+ "You start installing \the [tool] into [target]'s [affected.name].")
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] has installed \the [tool] into [target]'s [affected.name].", \
+ "\blue You have installed \the [tool] into [target]'s [affected.name].")
+
+ var/obj/item/device/mmi/M = tool
+ var/obj/item/organ/mmi_holder/holder = new(target, 1)
+ target.internal_organs_by_name["brain"] = holder
+ user.drop_from_inventory(tool)
+ tool.loc = holder
+ holder.stored_mmi = tool
+ holder.update_from_mmi()
+
+ if(M.brainmob && M.brainmob.mind)
+ M.brainmob.mind.transfer_to(target)
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ user.visible_message("\red [user]'s hand slips.", \
+ "\red Your hand slips.")
\ No newline at end of file
diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm
index 88876da9ed0..62bfaff907f 100644
--- a/code/modules/virus2/admin.dm
+++ b/code/modules/virus2/admin.dm
@@ -73,10 +73,11 @@
var/f = 1
for(var/k in all_species)
var/datum/species/S = all_species[k]
- if(!(S.flags & IS_SYNTHETIC))
- if(!f) H += " | "
- else f = 0
- H += "[k]"
+ if(S.virus_immune)
+ continue
+ if(!f) H += " | "
+ else f = 0
+ H += "[k]"
H += {"
Reset
diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm
index c1852a0cb98..62bd4153f59 100644
--- a/code/modules/virus2/disease2.dm
+++ b/code/modules/virus2/disease2.dm
@@ -45,7 +45,7 @@
var/list/res = list()
for (var/specie in all_species)
var/datum/species/S = all_species[specie]
- if(!(S.flags & IS_SYNTHETIC))
+ if(!S.virus_immune)
meat += S.name
if(meat.len)
var/num = rand(1,meat.len)
@@ -66,6 +66,12 @@
if(prob(5))
mob.antibodies |= antigen // 20% immunity is a good chance IMO, because it allows finding an immune person easily
+ // Some species are flat out immune to organic viruses.
+ var/mob/living/carbon/human/H = mob
+ if(istype(H) && H.species.virus_immune)
+ cure(mob)
+ return
+
if(mob.radiation > 50)
if(prob(1))
majormutate()
diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm
index 2cac2551044..d2671b7933c 100644
--- a/code/modules/virus2/helpers.dm
+++ b/code/modules/virus2/helpers.dm
@@ -3,25 +3,26 @@ proc/infection_check(var/mob/living/carbon/M, var/vector = "Airborne")
if (!istype(M))
return 0
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && H.species.virus_immune)
+ return 0
+
var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage.
var/score = round(0.06*protection) //scales 100% protection to 6.
switch(vector)
if("Airborne")
- if(M.internal)
- score = 6 //not breathing infected air helps greatly
- var/obj/item/I = M.wear_mask
-
- //masks provide a small bonus and can replace overall bio protection
- if(I)
- score = max(score, round(0.06*I.armor["bio"]))
- if (istype(I, /obj/item/clothing/mask))
- score += 1 //this should be added after
+ if(M.internal) //not breathing infected air helps greatly
+ return 0
+ var/obj/item/I = M.wear_mask
+ //masks provide a small bonus and can replace overall bio protection
+ if(I)
+ score = max(score, round(0.06*I.armor["bio"]))
+ if (istype(I, /obj/item/clothing/mask))
+ score += 1 //this should be added after
if("Contact")
- if(istype(M, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
-
+ if(istype(H))
//gloves provide a larger bonus
if (istype(H.gloves, /obj/item/clothing/gloves))
score += 2
diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm
index 7508818a6d7..d318ca9f8ad 100644
--- a/code/modules/virus2/items_devices.dm
+++ b/code/modules/virus2/items_devices.dm
@@ -16,7 +16,7 @@
var/mob/living/carbon/C = M
if (istype(C,/mob/living/carbon/human/))
var/mob/living/carbon/human/H = C
- if(H.species && H.species.flags & NO_BLOOD)
+ if(H.species.flags & NO_BLOOD)
report("Scan aborted: The target does not have blood.", user)
return
diff --git a/code/setup.dm b/code/setup.dm
index cbd079c9a5d..80074d2afc0 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -645,11 +645,10 @@ var/list/be_special_flags = list(
#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon.
#define IS_PLANT 1024 // Is a treeperson.
#define IS_WHITELISTED 2048 // Must be whitelisted to play.
-#define IS_SYNTHETIC 4096 // Is a machine race.
-#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen. (RGB)
-#define CAN_JOIN 16384 // Species is selectable in chargen.
-#define IS_RESTRICTED 32768 // Is not a core/normally playable species. (castes, mutantraces)
-#define REGENERATES_LIMBS 65536 // Attempts to regenerate unamputated limbs.
+#define HAS_EYE_COLOR 4096 // Eye colour selectable in chargen. (RGB)
+#define CAN_JOIN 8192 // Species is selectable in chargen.
+#define IS_RESTRICTED 16384 // Is not a core/normally playable species. (castes, mutantraces)
+// unused: 32768 - higher than this will overflow
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
@@ -719,11 +718,12 @@ var/list/be_special_flags = list(
#define NETWORK_FAILURE 32
// Some on_mob_life() procs check for alien races.
-#define IS_DIONA 1
-#define IS_VOX 2
-#define IS_SKRELL 3
-#define IS_UNATHI 4
-#define IS_XENOS 5
+#define IS_DIONA 1
+#define IS_VOX 2
+#define IS_SKRELL 3
+#define IS_UNATHI 4
+#define IS_XENOS 5
+#define IS_MACHINE 6
#define MAX_GEAR_COST 5 // Used in chargen for accessory loadout limit.
@@ -984,3 +984,5 @@ var/list/be_special_flags = list(
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
+// Damage above this value must be repaired with surgery.
+#define ROBOLIMB_SELF_REPAIR_CAP 30
\ No newline at end of file
diff --git a/html/changelogs/Zuhayr-IPC.yml b/html/changelogs/Zuhayr-IPC.yml
new file mode 100644
index 00000000000..623c01c723e
--- /dev/null
+++ b/html/changelogs/Zuhayr-IPC.yml
@@ -0,0 +1,14 @@
+author: Zuhayr
+delete-after: True
+changes:
+ - rscadd: "Prosthetic limbs are now only repairable with welders/cable coils if they have suffered below 30 combined damage."
+ - rscadd: "Surgery steps that cause no pain and have no failure wounding have been added: screwdriver for 'incision', crowbar to open, multitool to 'decouple' a prosthetic organ. Hemostat is still used to take an organ out."
+ - rscadd: "Using a welder or a cable coil as a surgical tool after opening a maintenance hatch will repair damage beyond the 30 damage cap. In other words, severe damage to robolimbs requires expert repair from someone else."
+ - rscdel: "Eye and brain surgery were removed; they predate the current organ system and are redundant."
+ - rscadd: "IPC are now simply full prosthetic bodies using a specific manufacturer (Morpheus Cyberkinetics)."
+ - rscadd: "IPC can 'recharge' in a cyborg station to regain nutriment. They no longer interface with APCs."
+ - rscadd: "NO_BLOOD flag now bypasses ingested and blood reagent processing."
+ - rscadd: "NO_SCAN now bypasses mutagen reagent effects."
+ - rscadd: "Cyborg analyzers now show damage to prosthetic limbs and organs on humans."
+ - tweak: "Prosthetic EMP damage was reduced."
+ - tweak: "Several organ files were split up/moved around."
\ No newline at end of file
diff --git a/icons/mob/human_races/cyberlimbs/ipc.dmi b/icons/mob/human_races/cyberlimbs/ipc.dmi
new file mode 100644
index 00000000000..b0ae6739177
Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/ipc.dmi differ
diff --git a/icons/mob/human_races/r_machine.dmi b/icons/mob/human_races/r_machine.dmi
index 2e3956f8464..65f66c32385 100644
Binary files a/icons/mob/human_races/r_machine.dmi and b/icons/mob/human_races/r_machine.dmi differ