More cybernetic organs and additional organ functions (#13089)

* someone fucking broke tails again thanks guys

* adds "organ efficiency", a modifier for how strong an organ is in generic organ-related activities
gives higher organ efficiency to several upgraded cybernetic organs, alongside with the generic organ-related activities it does stuff with
adds ghetto craftable organs, currently just the lungs and heart, which have lower max health and organ efficiency
adds cybernetic stomachs and ears
redoes the sprite for the cybernetic heart and makes it actually beat
switches the nanite heart to use the nanite organ icon

* did not mean to remove that

* Update organ_internal.dm

* Update code/modules/surgery/organs/lungs.dm

Co-authored-by: Hopekz <hopekxx@gmail.com>

* Update code/modules/surgery/organs/heart.dm

Co-authored-by: Hopekz <hopekxx@gmail.com>

Co-authored-by: Hopekz <hopekxx@gmail.com>
This commit is contained in:
Theos
2022-01-26 13:49:58 -05:00
committed by GitHub
parent b846d40797
commit e8c09e2fc0
14 changed files with 163 additions and 33 deletions

View File

@@ -426,6 +426,26 @@
time = 10 SECONDS
category = CAT_MISC
/datum/crafting_recipe/ghetto_heart
name = "Makeshift Heart"
result = /obj/item/organ/heart/ghetto
reqs = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1,
/obj/item/stack/cable_coil = 3,
/obj/item/weaponcrafting/receiver = 1, //it recieves the blood
/obj/item/reagent_containers/hypospray/medipen/pumpup = 1)
tools = list(TOOL_WIRECUTTER, TOOL_WELDER)
time = 15 SECONDS
category = CAT_MISC
/datum/crafting_recipe/ghetto_lungs
name = "Makeshift Lungs"
result = /obj/item/organ/lungs/ghetto
reqs = list(/obj/item/tank/internals/emergency_oxygen = 2,
/obj/item/weaponcrafting/receiver = 1) //it recieves the oxygen
tools = list(TOOL_WELDER)
time = 15 SECONDS
category = CAT_MISC
/datum/crafting_recipe/mousetrap
name = "Mouse Trap"
result = /obj/item/assembly/mousetrap
@@ -806,7 +826,7 @@
result = /obj/item/reagent_containers/glass/bucket/wooden
category = CAT_PRIMAL
/datum/crafting_recipe/cleanleather
/datum/crafting_recipe/cleanleather
name = "Clean Leather"
result = /obj/item/stack/sheet/wetleather
reqs = list(/obj/item/stack/sheet/hairlesshide = 1, /datum/reagent/water = 20)

View File

@@ -32,6 +32,8 @@
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL(src) && !HAS_TRAIT(src, TRAIT_NOHUNGER))
var/obj/item/organ/heart = getorganslot(ORGAN_SLOT_HEART)
var/heart_ratio = heart ? heart.get_organ_efficiency() : 0.5 //slower blood regeneration without a heart, or with a broken one </3
var/nutrition_ratio = 0
switch(nutrition)
if(0 to NUTRITION_LEVEL_STARVING)
@@ -46,8 +48,9 @@
nutrition_ratio = 1
if(satiety > 80)
nutrition_ratio *= 1.25
nutrition_ratio *= heart_ratio
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
blood_volume = min(BLOOD_VOLUME_NORMAL(src), blood_volume + 0.5 * nutrition_ratio)
blood_volume = min(BLOOD_VOLUME_NORMAL(src), blood_volume + 0.5 * nutrition_ratio * heart_ratio)
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")

View File

@@ -54,16 +54,12 @@
/mob/living/carbon/handle_breathing(times_fired)
var/next_breath = 4
var/obj/item/organ/lungs/L = getorganslot(ORGAN_SLOT_LUNGS)
var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
if(L)
if(L.damage > L.high_threshold)
next_breath--
if(H)
if(H.damage > H.high_threshold)
next_breath--
if(L.damage)
next_breath *= L.get_organ_efficiency()
if((times_fired % next_breath) == 0 || failed_last_breath)
breathe() //Breathe per 4 ticks if healthy, down to 2 if our lungs or heart are damaged, unless suffocating
breathe() //Breathe per 4 ticks if healthy, down to 1 based on lung damage, unless suffocating
if(failed_last_breath)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
else

View File

@@ -543,6 +543,39 @@
category = list("Cybernetics", "Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_ears
name = "Cybernetic Ears"
desc = "A pair of cybernetic ears"
id = "cybernetic_ears"
build_type = PROTOLATHE | MECHFAB
construction_time = 40
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
build_path = /obj/item/organ/ears/cybernetic
category = list("Cybernetics", "Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_stomach
name = "Cybernetic stomach"
desc = "A cybernetic stomach"
id = "cybernetic_stomach"
build_type = PROTOLATHE | MECHFAB
construction_time = 40
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
build_path = /obj/item/organ/stomach/cybernetic
category = list("Cybernetics", "Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_stomach_u
name = "Cybernetic Ears"
desc = "An upgraded cybernetic stomach"
id = "cybernetic_stomach_u"
build_type = PROTOLATHE | MECHFAB
construction_time = 50
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 500, /datum/material/gold=200)
build_path = /obj/item/organ/stomach/cybernetic/upgraded
category = list("Cybernetics", "Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_appendix
name = "Cybernetic Appendix"
desc = "A replacement for those who lost a part of themselfs."

View File

@@ -521,7 +521,7 @@
display_name = "Cybernetic Organs"
description = "We have the technology to rebuild him."
prereq_ids = list("adv_biotech")
design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_appendix")
design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_stomach", "cybernetic_ears", "cybernetic_appendix")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
export_price = 5000
@@ -530,7 +530,7 @@
display_name = "Upgraded Cybernetic Organs"
description = "We have the technology to upgrade him."
prereq_ids = list("cyber_organs")
design_ids = list("cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u")
design_ids = list("cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u", "cybernetic_stomach_u")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
export_price = 5000

View File

@@ -39,7 +39,7 @@
else if(!(organ_flags & ORGAN_FAILING)) // if this organ is failing, do not clear deaf stacks.
deaf = max(deaf - 1, 0)
if(prob(damage / 20) && (damage > low_threshold))
adjustEarDamage(0, 4)
adjustEarDamage(0, 2)
SEND_SOUND(C, sound('sound/weapons/flash_ring.ogg'))
to_chat(C, span_warning("The ringing in your ears grows louder, blocking out any external noises for a moment."))
else if((organ_flags & ORGAN_FAILING) && (deaf == 0))
@@ -110,6 +110,14 @@
H.dna.species.mutant_bodyparts -= "ears"
H.update_body()
/obj/item/organ/ears/cybernetic
name = "cybernetic hearing apparatus"
desc = "A set of complex electronics that can mimic the functions of an ear. Slightly more resistant to damage."
icon_state = "ears-c"
damage_multiplier = 0.8
status = ORGAN_ROBOTIC
organ_flags = ORGAN_SYNTHETIC
/obj/item/organ/ears/penguin
name = "penguin ears"
desc = "The source of a penguin's happy feet."

View File

@@ -20,6 +20,11 @@
var/failed = FALSE //to prevent constantly running failing code
var/operated = FALSE //whether the heart's been operated on to fix some of its damages
/obj/item/organ/heart/Initialize()
. = ..()
icon_base = icon_state
update_icon()
/obj/item/organ/heart/update_icon()
if(beating)
icon_state = "[icon_base]-on"
@@ -46,12 +51,12 @@
/obj/item/organ/heart/proc/Stop()
beating = 0
update_icon()
return 1
return TRUE
/obj/item/organ/heart/proc/Restart()
beating = 1
update_icon()
return 1
return TRUE
/obj/item/organ/heart/prepare_eat()
var/obj/S = ..()
@@ -175,6 +180,14 @@
priority = 100 //it's an indicator you're dying, so it's very high priority
colour = "red"
/obj/item/organ/heart/ghetto
name = "so called 'maintenance heart'"
desc = "A haphazardly constructed device that can supposedly pump blood. Used by the desperate or insane."
icon_state = "heart-g"
maxHealth = 0.5 * STANDARD_ORGAN_THRESHOLD
organ_efficiency = 0.5
organ_flags = ORGAN_SYNTHETIC
/obj/item/organ/heart/cybernetic
name = "cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart."
@@ -189,8 +202,9 @@
/obj/item/organ/heart/cybernetic/upgraded
name = "upgraded cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma, regenerates after use."
desc = "An electronic device designed to mimic the functions of an organic human heart. Fitted with a blood synthesizer, it also holds an emergency epinephrine synthesizer that supplies a dosage if the body is critically damaged."
icon_state = "heart-c-u"
organ_efficiency = 1.5
var/dose_available = TRUE
var/rid = /datum/reagent/medicine/epinephrine
var/ramount = 10
@@ -207,7 +221,7 @@
/obj/item/organ/heart/cybernetic/upgraded/emp_act()
. = ..()
addtimer(CALLBACK(src, .proc/Restart), 80) //Can restart itself after an EMP so it isnt an insta death
addtimer(CALLBACK(src, .proc/Restart), 8 SECONDS) //Can restart itself after an EMP so it isnt an insta death
/obj/item/organ/heart/freedom
name = "heart of freedom"

View File

@@ -92,6 +92,7 @@
return FALSE
var/gas_breathed = 0
var/eff = get_organ_efficiency()
//Partial pressures in our breath
var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))
@@ -121,7 +122,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-5 * eff)
gas_breathed = breath.get_moles(/datum/gas/oxygen)
H.clear_alert("not_enough_oxy")
@@ -149,7 +150,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-5 * eff)
gas_breathed = breath.get_moles(/datum/gas/nitrogen)
H.clear_alert("nitro")
@@ -186,7 +187,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-5 * organ_efficiency)
gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
H.clear_alert("not_enough_co2")
@@ -216,7 +217,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-5 * eff)
gas_breathed = breath.get_moles(/datum/gas/plasma)
H.clear_alert("not_enough_tox")
@@ -281,7 +282,7 @@
H.adjustFireLoss(nitryl_pp/4)
gas_breathed = breath.get_moles(/datum/gas/nitryl)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/nitryl,1)
H.reagents.add_reagent(/datum/reagent/nitryl,1*eff)
breath.adjust_moles(/datum/gas/nitryl, -gas_breathed)
@@ -299,7 +300,7 @@
H.adjustFireLoss(freon_pp/4)
gas_breathed = breath.get_moles(/datum/gas/freon)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/freon,1)
H.reagents.add_reagent(/datum/reagent/freon,1*eff)
breath.adjust_moles(/datum/gas/freon, -gas_breathed)
@@ -309,7 +310,7 @@
if(healium_pp > SA_sleep_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/healium)
ADD_TRAIT(H, TRAIT_SURGERY_PREPARED, "healium")
H.reagents.add_reagent(/datum/reagent/healium,max(0, 1 - existing))
H.reagents.add_reagent(/datum/reagent/healium,max(0, 1*eff - existing))
H.adjustFireLoss(-7)
H.adjustToxLoss(-5)
H.adjustBruteLoss(-5)
@@ -350,7 +351,7 @@
gas_breathed = breath.get_moles(/datum/gas/stimulum)
if (gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/stimulum)
H.reagents.add_reagent(/datum/reagent/stimulum,max(0, 1 - existing))
H.reagents.add_reagent(/datum/reagent/stimulum,max(0, 1*eff - existing))
breath.adjust_moles(/datum/gas/stimulum, -gas_breathed)
// Miasma
@@ -460,6 +461,18 @@
failed = FALSE
return
/obj/item/organ/lungs/attackby(obj/item/W, mob/user, params)
if(!(organ_flags & ORGAN_SYNTHETIC) && organ_efficiency == 1 && W.tool_behaviour == TOOL_CROWBAR)
user.visible_message(span_notice("[user] extends [src] with [W]!"), span_notice("You use [W] to extend [src]!"), "You hear something stretching.")
name = "extended [name]"
icon_state += "-crobar" //shh! don't tell anyone i handed you this card
safe_oxygen_min *= 2 //SCREAM LOUDER i dont know maybe eventually
safe_toxins_min *= 2
safe_nitro_min *= 2 //BREATHE HARDER
safe_co2_min *= 2
organ_efficiency = 2 //HOLD YOUR BREATH FOR REALLY LONG
maxHealth *= 0.5 //This procedure is not legal but i will do it for you
/obj/item/organ/lungs/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 5)
@@ -487,11 +500,10 @@
/obj/item/organ/lungs/xeno/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) //handling this externally so I don't have to nerf pluoxium, can't handle it internally without removing perpetual pluox or requiring plasma for breathing
. = ..()
if(!breath.total_moles())
return .
var/breath_amt = breath.get_moles(/datum/gas/plasma)
breath.adjust_moles(/datum/gas/plasma, -breath_amt)
breath.adjust_moles(/datum/gas/oxygen, breath_amt)
if(breath)
var/breath_amt = breath.get_moles(/datum/gas/plasma)
breath.adjust_moles(/datum/gas/plasma, -breath_amt)
breath.adjust_moles(/datum/gas/oxygen, breath_amt)
/obj/item/organ/lungs/slime
name = "vacuole"
@@ -505,6 +517,13 @@
var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
/obj/item/organ/lungs/ghetto
name = "oxygen tanks welded to a modular reciever"
desc = "A pair of oxygen tanks which have been attached to a modular (oxygen) receiver. They are incapable of supplying air, but can work as a replacement for lungs."
icon_state = "lungs_g"
organ_efficiency = 0.5
organ_flags = ORGAN_SYNTHETIC //the moment i understood the weakness of flesh, it disgusted me, and i yearned for the certainty, of steel
/obj/item/organ/lungs/cybernetic
name = "cybernetic lungs"
desc = "A cybernetic version of the lungs found in traditional humanoid entities. Slightly more effecient than organic lungs."
@@ -521,9 +540,10 @@
/obj/item/organ/lungs/cybernetic/upgraded
name = "upgraded cybernetic lungs"
desc = "A more advanced version of the stock cybernetic lungs, for use in hazardous environments. Features higher temperature tolerances and the ability to filter out most potentially harmful gases."
desc = "A more advanced version of the stock cybernetic lungs, more efficient at, well, breathing. Features higher temperature tolerances and the ability to filter out most potentially harmful gases."
icon_state = "lungs-c-u"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
organ_efficiency = 1.5
safe_oxygen_min = 10
safe_co2_max = 20
safe_toxins_max = 20 //Higher resistance to most harmful gasses

View File

@@ -10,7 +10,10 @@
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
var/organ_flags = 0
var/maxHealth = STANDARD_ORGAN_THRESHOLD
var/damage = 0 //total damage this organ has sustained
///total damage this organ has sustained
var/damage = 0
///how functional this organ is, higher numbers = stronger lower = garbage, scales multiplicitively with health (50% health = *50% efficiency)
var/organ_efficiency = 1
///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick
var/healing_factor = 0 //fraction of maxhealth healed per on_life(), set to 0 for generic organs
var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs
@@ -102,7 +105,6 @@
damage = max(0, damage - ((maxHealth * healing_factor) * (C.satiety / MAX_SATIETY) * 4))
check_damage_thresholds(C)
prev_damage = damage
return
/** check_damage_thresholds
* input: M (a mob, the owner of the organ we call the proc on)
@@ -191,6 +193,10 @@
/obj/item/organ/item_action_slot_check(slot,mob/user)
return //so we don't grant the organ's action to mobs who pick up the organ.
///returns an organ's efficiency, a percent value (rounded to the 10s) based on its damage and organ_efficiency
/obj/item/organ/proc/get_organ_efficiency()
return damage < low_threshold ? organ_efficiency : round(organ_efficiency * (damage/maxHealth), 0.1)
///Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
/obj/item/organ/proc/applyOrganDamage(var/d, var/maximum = maxHealth) //use for damaging effects
if(maximum < d + damage)

View File

@@ -1,3 +1,5 @@
#define NUTRI_STASH_MAX 8 //8 nutriment = 300 nutrition
/obj/item/organ/stomach
name = "stomach"
icon_state = "stomach"
@@ -84,6 +86,34 @@
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "disgust")
..()
/obj/item/organ/stomach/cybernetic
name = "cybernetic stomach"
desc = "A cybernetic metabolic furnace that can be connected to a digestive system in place of a stomach."
icon_state = "stomach-c"
maxHealth = 1.2 * STANDARD_ORGAN_THRESHOLD
status = ORGAN_ROBOTIC
organ_flags = ORGAN_SYNTHETIC
/obj/item/organ/stomach/cybernetic/upgraded
name = "upgraded cybernetic stomach"
desc = "An upgraded metabolic furnace that can be connected to a digestive system in place of a stomach. Both hardier and capable of storing excess nutrition if the body is already well sustained."
icon_state = "stomach-c-u"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
var/nutriment_stashed = 0
/obj/item/organ/stomach/cybernetic/upgraded/on_life()
if(owner.nutrition >= NUTRITION_LEVEL_FULL && nutriment_stashed < NUTRI_STASH_MAX)
var/datum/reagent/nutri = locate(/datum/reagent/consumable/nutriment) in owner.reagents.reagent_list
if(nutri)
var/amt_stored = min(nutri.volume, NUTRI_STASH_MAX - nutriment_stashed)
nutriment_stashed += amt_stored
owner.reagents.remove_reagent(/datum/reagent/consumable/nutriment, amt_stored)
..()
if(owner.nutrition <= NUTRITION_LEVEL_HUNGRY && nutriment_stashed)
owner.reagents.add_reagent(/datum/reagent/consumable/nutriment, nutriment_stashed)
nutriment_stashed = 0
to_chat(owner, span_notice("You feel less hungry..."))
/obj/item/organ/stomach/fly
name = "insectoid stomach"
icon_state = "stomach-x" //xenomorph liver? It's just a black liver so it fits.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1,7 +1,7 @@
/obj/item/organ/heart/nanite
name = "Nanite heart"
desc = "A specialized heart constructed from nanites that helps coordinate nanites allowing them to regenerate quicker inside the body without any ill effects. Caution this organ will fall apart without nanites to sustain itself!"
icon_state = "heart-x"
icon_state = "heart-nanites"
organ_flags = ORGAN_SYNTHETIC
var/nanite_boost = 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 378 B