diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index a1199642..19d78991 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -127,7 +127,9 @@
/obj/item/borg/upgrade/tasercooler,
/obj/item/borg/upgrade/jetpack),
- "Synthetic Coverings" = list( /obj/item/weapon/synth_skin_spray,
+ "Synthetic Shell Components" = list(
+ /obj/item/organ/eyes/robot,
+ /obj/item/weapon/synth_skin_spray,
/obj/item/weapon/synth_skin_cartridge/paint,
/obj/item/weapon/synth_skin_cartridge/skin,
/obj/item/weapon/synth_skin_cartridge/fur,
@@ -887,4 +889,4 @@
target.apply_damage(10, HALLOSS)
target.say("*scream")
spawn(10)
- user.visible_message("\red [user] stops the [src] and leaves [target] resting as they are.", "\red You turn the [src] off and let go of [target].")
\ No newline at end of file
+ user.visible_message("\red [user] stops the [src] and leaves [target] resting as they are.", "\red You turn the [src] off and let go of [target].")
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 1a0399fa..252a35bd 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -801,7 +801,17 @@
proc/stabilize_body_temperature()
if (species.flags & IS_SYNTHETIC)
- bodytemperature += species.synth_temp_gain //just keep putting out heat.
+ //TODO: Test these constants
+ var/temperatureModifier = 0 //all IS_SYNTHETIC species -need- radiators
+ if(!has_organ("radiator"))
+ temperatureModifier = 25
+ else
+ var/datum/organ/internal/Radiator = internal_organs_by_name["radiator"]
+ if(Radiator.is_broken())
+ temperatureModifier = 25
+ else if(Radiator.is_bruised())
+ temperatureModifier = 17
+ bodytemperature += species.synth_temp_gain + temperatureModifier //just keep putting out heat.
return
var/body_temperature_difference = species.body_temperature - bodytemperature
@@ -1432,15 +1442,26 @@
if(1) healths.icon_state = "health6"
if(2) healths.icon_state = "health7"
else
- //switch(health - halloss)
- switch(100 - ((species && species.flags & NO_PAIN & !IS_SYNTHETIC) ? 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"
- if(40 to 60) healths.icon_state = "health3"
- if(20 to 40) healths.icon_state = "health4"
- if(0 to 20) healths.icon_state = "health5"
- else healths.icon_state = "health6"
+ var/numb = 0
+ if (species && (species.flags & IS_SYNTHETIC))
+ var/datum/organ/internal/machine/Diagnosis_unit = internal_organs_by_name["diagnosis unit"]
+ if (Diagnosis_unit.is_broken())
+ numb = 1
+ else if (Diagnosis_unit.is_bruised() && prob(35))
+ numb = 1
+
+ if (numb)
+ healths.icon_state = "health_numb"
+ else
+ //switch(health - halloss)
+ switch(100 - ((species && species.flags & NO_PAIN & !IS_SYNTHETIC) ? 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"
+ if(40 to 60) healths.icon_state = "health3"
+ if(20 to 40) healths.icon_state = "health4"
+ if(0 to 20) healths.icon_state = "health5"
+ else healths.icon_state = "health6"
if(nutrition_icon)
switch(nutrition)
@@ -1483,7 +1504,18 @@
else bodytemp.icon_state = "temp-4"
else
var/temp_step
- if (bodytemperature >= species.body_temperature)
+ var/numb = 0
+ if (species && (species.flags & IS_SYNTHETIC))
+ var/datum/organ/internal/machine/Diagnosis_unit = internal_organs_by_name["diagnosis unit"]
+ if (Diagnosis_unit.is_broken())
+ numb = 1
+ else if (Diagnosis_unit.is_bruised() && prob(35))
+ numb = 1
+
+ if (numb)
+ bodytemp.icon_state = "temp_numb"
+
+ else if (bodytemperature >= species.body_temperature)
temp_step = (species.heat_level_1 - species.body_temperature)/4
if (bodytemperature >= species.heat_level_1)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index ddfb8577..6fc004aa 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -201,17 +201,17 @@
// Grabs the window recieved when you click-drag someone onto you.
/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H)
return
-
+
//Used by xenos understanding larvae and dionaea understanding nymphs.
/datum/species/proc/can_understand(var/mob/other)
return
-
-
+
+
/datum/species/proc/blend_preview_icon(var/icon/main_icon,var/datum/preferences/preferences,var/paint_colour)
if(paint_colour)
main_icon.Blend(paint_colour, ICON_ADD)
- return
+ return
if(flags & HAS_SKIN_COLOR)
main_icon.Blend(rgb(preferences.r_skin, preferences.g_skin, preferences.b_skin), ICON_ADD)
return
@@ -220,8 +220,8 @@
main_icon.Blend(rgb(preferences.s_tone, preferences.s_tone, preferences.s_tone), ICON_ADD)
else
main_icon.Blend(rgb(-preferences.s_tone, -preferences.s_tone, -preferences.s_tone), ICON_SUBTRACT)
-
-
+
+
/datum/species/proc/get_organ_preview_icon(var/name, var/robot, var/gendered, var/gender_string, var/datum/preferences/preferences, var/datum/synthetic_limb_cover/covering, var/paint_colour)
var/icon_name = icobase
if (robot)
@@ -236,7 +236,7 @@
var/icon/result = new /icon(icon_name,state_name)
blend_preview_icon(result,preferences,paint_colour)
return result
-
+
/datum/species/proc/get_is_preview_organ_robotic(var/name,var/datum/preferences/preferences)
if (flags & IS_SYNTHETIC)
@@ -245,7 +245,7 @@
var/list/organ_robotic_info=preferences.organ_data[name]
if (istype(organ_robotic_info))
return TRUE
-
+
/datum/species/proc/get_preview_organ_covering(var/name,var/datum/preferences/preferences)
if (name in preferences.organ_data)
var/list/organ_robotic_info=preferences.organ_data[name]
@@ -254,8 +254,8 @@
if (preferences.species=="Machine")
if (preferences.covering_type)
return list(preferences.covering_type,rgb(preferences.r_skin,preferences.g_skin,preferences.b_skin))
-
-
+
+
/datum/species/proc/get_tail_preview_icon(var/list/preview_coverings,var/datum/preferences/preferences)
var/tail_state=null
if (!(isnull(preview_coverings["groin"])))
@@ -268,8 +268,8 @@
var/icon/result = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = tail_state)
result.Blend(rgb(preferences.r_hair,preferences.g_hair,preferences.b_hair),ICON_ADD)
return result
-
-
+
+
/datum/species/proc/get_eyes_preview_icon(var/list/preview_coverings,var/datum/preferences/preferences)
var/eye_state=null
if (!(isnull(preview_coverings["head"])))
@@ -280,13 +280,13 @@
var/icon/result = new/icon('icons/mob/human_face.dmi',eye_state)
result.Blend(rgb(preferences.r_eyes,preferences.g_eyes,preferences.b_eyes),ICON_ADD)
return result
-
+
/* This function takes a preferences object and generates a complete body and hair icon for that set of preferences. It's needlessly complicated
and duplicates a lot of what's going on in update_icons. The two systems should be combined somehow, possibly by using a 'visual identity' object
-that could be created from either a living human or a preferences object and then passing that to a single render function, but I'll leave that
+that could be created from either a living human or a preferences object and then passing that to a single render function, but I'll leave that
exercise for another day.
-See code\modules\mob\new_player\preferences_setup.dm for where it's used.
+See code\modules\mob\new_player\preferences_setup.dm for where it's used.
- jack_fractal*/
/datum/species/proc/create_body_preview_icon(var/datum/preferences/preferences)
var/gender_string = (preferences.gender==FEMALE) ? "f" : "m"
@@ -578,7 +578,7 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
rarity_value = 2
eyes = "blank_eyes"
- brute_mod = 0.5
+ brute_mod = 1 //Fuck yo brute mod.
burn_mod = 1
warning_low_pressure = 50
@@ -602,6 +602,10 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/robot,
+ "eyes" = /datum/organ/internal/eyes/robot,
+ "radiator" = /datum/organ/internal/machine/radiator,
+ "chemical containment" = /datum/organ/internal/machine/bladder,
+ "diagnosis unit" = /datum/organ/internal/machine/diagnosis_unit,
)
/datum/species/machine/create_organs(var/mob/living/carbon/human/H)
..()
@@ -609,8 +613,8 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
if (istype(brain_datum))
if (isnull(brain_datum.machine_brain_type))
brain_datum.machine_brain_type="Posibrain"
-
-
+
+
/datum/species/bug
name = "Vaurca"
name_plural = "varucae"
@@ -778,4 +782,4 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
if(slot_back in equip_slots)
equip_slots |= slot_in_backpack
- equip_slots |= slot_legcuffed
\ No newline at end of file
+ equip_slots |= slot_legcuffed
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index bb03edb4..b5208494 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -147,6 +147,7 @@
var/brute = 0
var/burn = 0
var/icon_state_broken = "broken"
+ var/obj/item/organ/organ_type = null // for shells. Only define if this can be placed inside an IPC during organ replacement surgery.
// TODO: actual icons ;)
/obj/item/robot_parts/robot_component/binary_communication_device
@@ -168,7 +169,8 @@
name = "camera"
icon_state = "camera"
icon_state_broken = "camera_broken"
-
+ organ_type = /obj/item/organ/eyes/robot
+
/obj/item/robot_parts/robot_component/law_computer
name = "law computer"
icon_state = "radio"
@@ -178,12 +180,25 @@
name = "diagnosis unit"
icon_state = "analyser"
icon_state_broken = "analyser_broken"
+ organ_type = /obj/item/organ/machine/diagnosis_unit
/obj/item/robot_parts/robot_component/radio
name = "radio"
icon_state = "radio"
icon_state_broken = "radio_broken"
+/obj/item/robot_parts/robot_component/radiator
+ name = "radiator"
+ icon_state = "radiator"
+ icon_state_broken = "radiator_broken"
+ organ_type = /obj/item/organ/machine/radiator
+
+/obj/item/robot_parts/robot_component/bladder
+ name = "chemical containment"
+ icon_state = "bladder"
+ icon_state_broken = "bladder_broken"
+ organ_type = /obj/item/organ/machine/bladder
+
//
//Robotic Component Analyser, basically a health analyser for robots
//
@@ -227,7 +242,7 @@
user.show_message("\t Damage Specifics: [BU] - [BR]")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
-
+
if (istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
@@ -245,7 +260,7 @@
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 (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
@@ -258,8 +273,8 @@
(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)
-
+
src.add_fingerprint(user)
return
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
index 9d4bfa0b..9300c55d 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/organ_alien.dm
@@ -224,4 +224,119 @@
robotic = 2
/obj/item/organ/stack/vox
- name = "vox cortical stack"
\ No newline at end of file
+ name = "vox cortical stack"
+
+//IPC/SHELL ORGANS.
+//TODO: Make the robot_components required for these
+//TODO: Make said components printable
+//TODO: sprites
+/datum/organ/internal/machine
+ removed_type = /obj/item/organ/machine
+
+/datum/organ/internal/machine/process()
+ return
+
+/datum/organ/internal/machine/radiator
+ name = "internal cooling unit"
+ parent_organ = "chest"
+ robotic = 2
+ min_bruised_damage = 15
+ min_broken_damage = 40
+ removed_type = /obj/item/organ/machine/radiator
+
+/obj/item/organ/machine/radiator
+ name = "internal cooling unit"
+ icon_state = "radiator"
+ organ_tag = "radiator"
+ organ_type = /datum/organ/internal/machine/radiator
+ robotic = 2
+
+/obj/item/organ/machine/radiator/exposed_to_the_world()
+ var/obj/item/robot_parts/robot_component/radiator/Radiator = new(src.loc)
+ if(organ_data.damage)
+ Radiator.brute = organ_data.damage
+ del(src)
+ return Radiator
+
+/datum/organ/internal/machine/bladder
+ name = "chemical containment"
+ parent_organ = "groin"
+ robotic = 2
+ removed_type = /obj/item/organ/machine/bladder
+
+/datum/organ/internal/machine/bladder/process()
+ if(is_bruised())
+ var/leakSmall = rand(1,25)
+ if(owner.reagents.total_volume > 0)
+ owner.reagents.remove_any(leakSmall)
+ if(owner.reagents.maximum_volume > 500)
+ owner.reagents.maximum_volume -= leakSmall
+
+ if(is_broken())
+ var/leakLarge = rand(25,50)
+ if(owner.reagents.total_volume > 0)
+ owner.reagents.remove_any(leakLarge)
+ if(owner.reagents.maximum_volume > 0)
+ if(owner.reagents.maximum_volume < leakLarge)
+ owner.reagents.maximum_volume = 0
+ else
+ owner.reagents.maximum_volume -= leakLarge
+
+ if(!is_bruised() && !is_broken() && owner.reagents.maximum_volume < 1000)
+ owner.reagents.maximum_volume = 1000
+
+ if(owner.reagents.reagent_list.len)
+ if(owner.reagents.has_reagent("sacid") || owner.reagents.has_reagent("pacid"))
+ take_damage(rand(0,2.5), 1)
+
+/obj/item/organ/machine/bladder
+ name = "chemical containment"
+ icon_state = "bladder"
+ organ_tag = "chemical containment"
+ organ_type = /datum/organ/internal/machine/bladder
+ robotic = 2
+
+/obj/item/organ/machine/bladder/replaced(var/mob/living/carbon/human/target)
+ if(istype(target) && (target.species.flags & IS_SYNTHETIC))
+ if(target.reagents.maximum_volume < 1000)
+ target.reagents.maximum_volume = 1000
+
+ ..()
+
+/obj/item/organ/machine/bladder/removed(var/mob/living/target, var/mob/living/user)
+ ..()
+
+ if(istype(target, /mob/living/carbon/human))
+ var/mob/living/carbon/human/Machine = target
+ if(Machine.species.flags & IS_SYNTHETIC)
+ Machine.reagents.clear_reagents()
+ Machine.reagents.maximum_volume = 0
+
+/obj/item/organ/machine/bladder/exposed_to_the_world()
+ msg_scopes("We went here x2.")
+ var/obj/item/robot_parts/robot_component/bladder/Bladder = new(src.loc)
+ if(organ_data.damage)
+ Bladder.brute = organ_data.damage
+ del(src)
+ return Bladder
+
+/datum/organ/internal/machine/diagnosis_unit
+ name = "diagnosis unit"
+ parent_organ = "head"
+ robotic = 2
+ removed_type = /obj/item/organ/machine/diagnosis_unit
+
+/obj/item/organ/machine/diagnosis_unit
+ name = "diagnosis unit"
+ icon_state = "diagnosis_unit"
+ organ_tag = "diagnosis unit"
+ organ_type = /datum/organ/internal/machine/diagnosis_unit
+ robotic = 2
+
+/obj/item/organ/machine/diagnosis_unit/exposed_to_the_world()
+ msg_scopes("We went here.")
+ var/obj/item/robot_parts/robot_component/diagnosis_unit/Diagnosis_unit = new(src.loc)
+ if(organ_data.damage)
+ Diagnosis_unit.brute = organ_data.damage
+ del(src)
+ return Diagnosis_unit
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index 3ee262b7..53f28e83 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -249,12 +249,12 @@
parent_organ = "head"
removed_type = /obj/item/organ/brain
vital = 1
-
-
+
+
/datum/organ/internal/brain/robot // brains for shells
- var/machine_brain_type=null
-
-
+ var/machine_brain_type=null
+
+
/datum/organ/internal/brain/robot/proc/create_robot_brain_replacement(var/target,var/new_location)
var/obj/item/device/mmi/new_mmi
if (machine_brain_type=="Posibrain")
@@ -267,7 +267,7 @@
new_mmi.transfer_identity(target)
new_mmi.loc = new_location
return new_mmi
-
+
/datum/organ/internal/brain/xeno
removed_type = /obj/item/organ/brain/xeno
@@ -284,6 +284,11 @@
if(is_broken())
owner.eye_blind = 20
+/datum/organ/internal/eyes/robot // eyes for shells
+ name = "charge-coupled device"
+ parent_organ = "head"
+ removed_type = /obj/item/organ/eyes/robot
+
/datum/organ/internal/appendix
name = "appendix"
parent_organ = "groin"
@@ -306,4 +311,4 @@
removed_organ.update()
organ_holder = removed_organ
- return removed_organ
\ No newline at end of file
+ return removed_organ
diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm
index c375cbb4..2340a34e 100644
--- a/code/modules/organs/organ_objects.dm
+++ b/code/modules/organs/organ_objects.dm
@@ -150,6 +150,19 @@
/obj/item/organ/eyes/prosthetic
robotic = 2
+/obj/item/organ/eyes/robot
+ name = "charge-coupled device"
+ icon_state = ""
+ organ_type = /datum/organ/internal/eyes/robot
+ robotic = 2
+
+ exposed_to_the_world()
+ var/obj/item/robot_parts/robot_component/camera/Camera = new()
+ if(organ_data.damage)
+ Camera.brute = organ_data.damage
+ del(src)
+ return Camera
+
/obj/item/organ/liver/prosthetic
robotic = 2
@@ -180,11 +193,11 @@
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (JMP)")
target.death()
-
+
/obj/item/organ/proc/exposed_to_the_world() // this is only useful for organs that change when actually removed from the body
- return
-
-
+ return
+
+
/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user)
..()
@@ -277,4 +290,4 @@
if(fingerprintslast) O.fingerprintslast = fingerprintslast
user.put_in_active_hand(O)
- del(src)
\ No newline at end of file
+ del(src)
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index 0cf7dfef..b9a234aa 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -17,10 +17,11 @@
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
+ if (target.species && (target.species.flags & IS_SYNTHETIC) && affected.internal_organs.len)
+ return 1
+ else
+ return 0
return 1
/datum/surgery_step/generic/cut_with_laser
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 3ea958bb..77076203 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -320,7 +320,8 @@
/datum/surgery_step/internal/replace_organ
allowed_tools = list(
- /obj/item/organ = 100
+ /obj/item/organ = 100,
+ /obj/item/robot_parts/robot_component = 100
)
min_duration = 60
@@ -334,7 +335,16 @@
var/organ_compatible
var/organ_missing
- if(!istype(O))
+ if(!istype(O) && istype(O, /obj/item/robot_parts/robot_component))
+ msg_scopes("Component's type: [tool.type].")
+ var/obj/item/robot_parts/robot_component/A = tool
+ msg_scopes("Component's organ_type: [A.organ_type].")
+ if(A.organ_type)
+ O = new A.organ_type()
+ O.update()
+ else
+ return 0
+ else
return 0
if(!target.species)
@@ -357,6 +367,19 @@
user << "\red \The [target] already has [o_a][O.organ_tag]."
return 2
+ msg_scopes("Affected.name: [affected.name].")
+ msg_scopes("Parent_organ: [O.organ_data.parent_organ].")
+ msg_scopes("Organ_data.type: [O.organ_data.type].")
+ if(O.organ_data)
+ msg_scopes("We have organ data.")
+ else
+ msg_scopes("No organ data.")
+
+ if(affected.name == O.organ_data.parent_organ)
+ msg_scopes("Affected name matches parent_organ.")
+ else
+ msg_scopes("Affected name does not match parent_organ.")
+
if(O.organ_data && affected.name == O.organ_data.parent_organ)
organ_compatible = 1
else
@@ -383,6 +406,11 @@
var/obj/item/organ/O = tool
if(istype(O))
O.replaced(target,affected)
+ else if(istype(tool, /obj/item/robot_parts/robot_component))
+ var/obj/item/robot_parts/robot_component/A = tool
+ if(A.organ_type)
+ O = A.organ_type
+ O.replaced(target,affected)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, damaging \the [tool]!", \
@@ -455,4 +483,4 @@
// max_duration = 40
// can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
-// return ..() && target.op_stage.ribcage == 2
\ No newline at end of file
+// return ..() && target.op_stage.ribcage == 2