mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-16 04:34:21 +00:00
* Robotic organ and disease improvements (#76766) ## About The Pull Request In the code description for the `ORGAN_ROBOTIC` flag, it says that robotic organs are not supposed to decay or regenerate health. I went and fixed this and added some more "robotic" behavior. New changes for robotic organs: - No longer heal damage passively - No longer gain health from revival - No longer heal in the smart organ fridge - No longer heal from pluoxium - Robotic ears no longer heal from ear healing items (earmuffs, etc.) - Robotic eyes are immune to changeling blind stings - Robotic eyes no longer heal from occuline New changes for diseases: - Some diseases now require an organ to work. A robotic organ will give immunity to the disease symptom unless the disease has "Inorganic Biology". - The transmission methods for diseases require organs to work but robotic organs are immune. (except inorganic biology) Airborne disease transmission require lungs. Ingested (drunk or eaten) disease transmission requires a stomach. Blood (inject or patch) disease transmission requires a heart. - Organs removed from a mob that is afflicted with a disease will be infectious while handling or transplanting it. (again, robotic organs are immune unless inorganic biology is present) Certain admin spawned or special diseases are exempt from this transmission method. - A stomach is required for nebula nausea, gastritium, carpellosis, metabolic boost, vomit, weight loss, death sandwich poisoning, - Lungs are required for choking, asphyxiation, cough, cold9, oxygen restoration, sneezing, flu, cold, spanish flu, tuberculosis - A liver is required for tissue hydration, plasma fixation, parasitic infection - Ears are required for deafness, sensory restoration - A heart is required for toxolysis, heart failure - Eyes are required for sensory restoration, hyphema - A tongue is required for voice change, parrot possession, pierrot throat - Wizarditis no longer requires a head (wtf?) to function ## Why It's Good For The Game Robotic organs should behave as intended. Not naturally healing (like organic organs) was supposed to be their downside to counteract their their ability to not decay upon death. ## Changelog 🆑 fix: Fix robotic organs to not gain health passively, from revival, smart organ fridge, pluxium, occuline, and earmuffs. add: Some diseases now require the appropriate internal organ to work. A robotic organ will give immunity to the disease symptom unless the disease has "Inorganic Biology". add: Disease transmission methods now require an internal organ to be successful. Robotic organs give immunity. (except inorganic biology) Airborne disease transmission require lungs. Ingested (drunk or eaten) disease transmission requires a stomach. Blood (inject or patch) disease transmission requires a heart. add: Organs removed from a mob that is afflicted with a disease will be infectious while handling or transplanting it. (again, robotic organs are immune unless inorganic biology is present) Certain admin spawned or special diseases are exempt from this transmission method. add: A stomach is required for nebula nausea, gastritium, carpellosis, metabolic boost, vomit, weight loss, death sandwich poisoning add: Lungs are required for choking, asphyxiation, cough, cold9, oxygen restoration, sneezing, flu, cold, spanish flu, tuberculosis add: A liver is required for tissue hydration, plasma fixation, parasitic infection add: Ears are required for deafness, sensory restoration add: A heart is required for toxolysis, heart failure add: Eyes are required for sensory restoration, hyphema add: A tongue is required for voice change, pierrot throat bal: Remove head requirement for wizarditis disease /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> * Modular parts * Printing time * Hah typos * I cant spell * Golden Shower feedback * Posi-Time * Update modular_skyrat/modules/synths/code/bodyparts/brain.dm --------- Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
164 lines
5.6 KiB
Plaintext
164 lines
5.6 KiB
Plaintext
/datum/component/infective
|
|
var/list/datum/disease/diseases //make sure these are the static, non-processing versions!
|
|
var/expire_time
|
|
var/required_clean_types = CLEAN_TYPE_DISEASE
|
|
/// The infection is weak and can only infect on consumption with small chance
|
|
var/is_weak = FALSE
|
|
/// Chance of weak infection on consumption
|
|
var/weak_infection_chance = 10
|
|
|
|
|
|
/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in, weak = FALSE)
|
|
if(islist(_diseases))
|
|
diseases = _diseases
|
|
else
|
|
diseases = list(_diseases)
|
|
if(expire_in)
|
|
expire_time = world.time + expire_in
|
|
QDEL_IN(src, expire_in)
|
|
|
|
if(!ismovable(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
is_weak = weak
|
|
|
|
if(is_weak && isitem(parent))
|
|
RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat))
|
|
RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat))
|
|
else
|
|
var/static/list/disease_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(try_infect_crossed),
|
|
)
|
|
AddComponent(/datum/component/connect_loc_behalf, parent, disease_connections)
|
|
|
|
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, PROC_REF(try_infect_buckle))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(try_infect_collide))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(try_infect_impact_zone))
|
|
if(isitem(parent))
|
|
RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(try_infect_attack_zone))
|
|
RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(try_infect_attack))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(try_infect_equipped))
|
|
RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat))
|
|
RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat))
|
|
if(istype(parent, /obj/item/reagent_containers/cup))
|
|
RegisterSignal(parent, COMSIG_GLASS_DRANK, PROC_REF(try_infect_drink))
|
|
if(isorgan(parent))
|
|
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion))
|
|
else if(istype(parent, /obj/effect/decal/cleanable/blood/gibs))
|
|
RegisterSignal(parent, COMSIG_GIBS_STREAK, PROC_REF(try_infect_streak))
|
|
|
|
/datum/component/infective/proc/on_organ_insertion(obj/item/organ/target, mob/living/carbon/receiver)
|
|
SIGNAL_HANDLER
|
|
|
|
for(var/datum/disease/disease in diseases)
|
|
receiver.ForceContractDisease(disease)
|
|
|
|
qdel(src) // once organ is implanted delete the infective component
|
|
|
|
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!eater.has_quirk(/datum/quirk/deviant_tastes))
|
|
eater.add_mood_event("disgust", /datum/mood_event/disgust/dirty_food)
|
|
|
|
if(is_weak && !prob(weak_infection_chance))
|
|
return
|
|
|
|
for(var/datum/disease/disease in diseases)
|
|
if(!disease.has_required_infectious_organ(eater, ORGAN_SLOT_STOMACH))
|
|
continue
|
|
|
|
eater.ForceContractDisease(disease)
|
|
|
|
try_infect(feeder, BODY_ZONE_L_ARM)
|
|
|
|
/datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder)
|
|
SIGNAL_HANDLER
|
|
|
|
var/appendage_zone = feeder.held_items.Find(source)
|
|
appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM
|
|
try_infect(feeder, appendage_zone)
|
|
|
|
for(var/datum/disease/disease in diseases)
|
|
if(!disease.has_required_infectious_organ(drinker, ORGAN_SLOT_STOMACH))
|
|
continue
|
|
|
|
drinker.ForceContractDisease(disease)
|
|
|
|
/datum/component/infective/proc/clean(datum/source, clean_types)
|
|
SIGNAL_HANDLER
|
|
|
|
. = NONE
|
|
if(clean_types & required_clean_types)
|
|
qdel(src)
|
|
return COMPONENT_CLEANED
|
|
|
|
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
|
|
SIGNAL_HANDLER
|
|
|
|
if(isliving(M))
|
|
try_infect(M)
|
|
|
|
/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
|
|
SIGNAL_HANDLER
|
|
|
|
var/atom/movable/P = parent
|
|
if(P.throwing)
|
|
//this will be handled by try_infect_impact_zone()
|
|
return
|
|
if(isliving(A))
|
|
try_infect(A)
|
|
|
|
/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
|
|
SIGNAL_HANDLER
|
|
|
|
try_infect(target, hit_zone)
|
|
|
|
/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
|
|
SIGNAL_HANDLER
|
|
|
|
try_infect(user, BODY_ZONE_L_ARM)
|
|
try_infect(target, hit_zone)
|
|
|
|
/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user)
|
|
SIGNAL_HANDLER
|
|
if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone
|
|
try_infect(target)
|
|
try_infect(user, BODY_ZONE_L_ARM)
|
|
|
|
/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
|
|
SIGNAL_HANDLER
|
|
|
|
var/old_bio_armor
|
|
if(isitem(parent))
|
|
//if you are putting an infective item on, it obviously will not protect you, so set its bio armor low enough that it will never block ContactContractDisease()
|
|
var/obj/item/equipped_item = parent
|
|
old_bio_armor = equipped_item.get_armor_rating(BIO)
|
|
equipped_item.set_armor_rating(BIO, 0)
|
|
|
|
try_infect(L, slot2body_zone(slot))
|
|
|
|
if(isitem(parent))
|
|
var/obj/item/equipped_item = parent
|
|
equipped_item.set_armor_rating(BIO, old_bio_armor)
|
|
|
|
/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
|
|
if(isliving(arrived))
|
|
try_infect(arrived, BODY_ZONE_PRECISE_L_FOOT)
|
|
|
|
/datum/component/infective/proc/try_infect_streak(datum/source, list/directions, list/output_diseases)
|
|
SIGNAL_HANDLER
|
|
|
|
// This blood is not infectable / does not have a diseases list
|
|
if(!islist(output_diseases))
|
|
return
|
|
|
|
output_diseases |= diseases
|
|
|
|
/datum/component/infective/proc/try_infect(mob/living/L, target_zone)
|
|
for(var/V in diseases)
|
|
L.ContactContractDisease(V, target_zone)
|