diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 21389f72482..75e5bba3386 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -56,6 +56,7 @@ //Organ defines for carbon mobs #define ORGAN_ORGANIC 1 #define ORGAN_ROBOTIC 2 +#define ORGAN_MINERAL 3 // Used for the plasmaman liver #define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/species/human/bodyparts_greyscale.dmi' #define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi' diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index a709b32c0ca..9e7c02b2f07 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -219,6 +219,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///This carbon doesn't bleed #define TRAIT_NOBLOOD "noblood" #define TRAIT_NOMETABOLISM "no_metabolism" +// Use when you want a mob to be able to metabolize plasma temporarily (e.g. plasma fixation disease symptom) +#define TRAIT_PLASMA_LOVER_METABOLISM "plasma_lover_metabolism" #define TRAIT_NOCLONELOSS "no_cloneloss" #define TRAIT_TOXIMMUNE "toxin_immune" #define TRAIT_EASYDISMEMBER "easy_dismember" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 7979091511b..dfde04baa2a 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -62,6 +62,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NOGUNS" = TRAIT_NOGUNS, "TRAIT_NOHUNGER" = TRAIT_NOHUNGER, "TRAIT_NOMETABOLISM" = TRAIT_NOMETABOLISM, + "TRAIT_PLASMA_LOVER_METABOLISM" = TRAIT_PLASMA_LOVER_METABOLISM, "TRAIT_NOCLONELOSS" = TRAIT_NOCLONELOSS, "TRAIT_TOXIMMUNE" = TRAIT_TOXIMMUNE, "TRAIT_EASYDISMEMBER" = TRAIT_EASYDISMEMBER, diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 745ca0d9d2f..c83bcd001fe 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -476,8 +476,18 @@ return TRUE return FALSE -///Determines the rate at which Plasma Fixation heals based on the amount of plasma in the air +/// Determines the rate at which Plasma Fixation heals based on the amount of plasma in the air #define HEALING_PER_MOL 1.1 +/// Determines the rate at which Plasma Fixation heals based on the amount of plasma being breathed through internals +#define HEALING_PER_BREATH_PRESSURE 0.05 +/// Determines the highest amount you can be healed for when breathing plasma from internals +#define MAX_HEAL_COEFFICIENT_INTERNALS 0.75 +/// Determines the highest amount you can be healed for from pulling plasma from the environment +#define MAX_HEAL_COEFFICIENT_ENVIRONMENT 0.5 +/// Determines the highest amount you can be healed for when there is plasma in the bloodstream +#define MAX_HEAL_COEFFICIENT_BLOODSTREAM 0.75 +/// This is the base heal amount before being multiplied by the healing coefficients +#define BASE_HEAL_PLASMA_FIXATION 4 /datum/symptom/heal/plasma name = "Plasma Fixation" @@ -503,24 +513,59 @@ if(A.totalTransmittable() >= 6) temp_rate = 4 -/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob +// We do this to prevent liver damage from injecting plasma when plasma fixation virus reaches stage 4 and beyond +/datum/symptom/heal/plasma/on_stage_change(datum/disease/advance/advanced_disease) + . = ..() + if(!.) + return FALSE + + if(advanced_disease.stage >= 4) + ADD_TRAIT(advanced_disease.affected_mob, TRAIT_PLASMA_LOVER_METABOLISM, DISEASE_TRAIT) + else + REMOVE_TRAIT(advanced_disease.affected_mob, TRAIT_PLASMA_LOVER_METABOLISM, DISEASE_TRAIT) + return TRUE + +/datum/symptom/heal/plasma/End(datum/disease/advance/advanced_disease) + . = ..() + if(!.) + return + + REMOVE_TRAIT(advanced_disease.affected_mob, TRAIT_PLASMA_LOVER_METABOLISM, DISEASE_TRAIT) + +// Check internals breath, environmental plasma, and plasma in bloodstream to determine the heal power +/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/advanced_disease) + var/mob/living/diseased_mob = advanced_disease.affected_mob var/datum/gas_mixture/environment var/list/gases . = 0 - if(M.loc) - environment = M.loc.return_air() + // Check internals + /// the amount of mols in a breath is significantly lower than in the environment so we are just going to use the tank's + /// distribution pressure as an abstraction rather than calculate it using the ideal gas equation. + /// balanced around a tank set to 4kpa = about 0.2 healing power. maxes out at 0.75 healing power, or 15kpa. + if(iscarbon(diseased_mob)) + var/mob/living/carbon/breather = diseased_mob + var/obj/item/tank/internals/internals_tank = breather.internal + if(internals_tank) + var/datum/gas_mixture/tank_contents = internals_tank.return_air() + if(tank_contents && round(tank_contents.return_pressure())) // make sure the tank is not empty or 0 pressure + if(tank_contents.gases[/datum/gas/plasma]) + // higher tank distribution pressure leads to more healing, but once you get to about 15kpa you reach the max + . += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, internals_tank.distribute_pressure * HEALING_PER_BREATH_PRESSURE) + // Check environment + if(diseased_mob.loc) + environment = diseased_mob.loc.return_air() if(environment) gases = environment.gases if(gases[/datum/gas/plasma]) - . += power * min(0.5, gases[/datum/gas/plasma][MOLES] * HEALING_PER_MOL) - if(M.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE)) - . += power * 0.75 //Determines how much the symptom heals if injected or ingested + . += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, gases[/datum/gas/plasma][MOLES] * HEALING_PER_MOL) + // Check for reagents in bloodstream + if(diseased_mob.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE)) + . += power * MAX_HEAL_COEFFICIENT_BLOODSTREAM //Determines how much the symptom heals if injected or ingested /datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = 4 * actual_power + var/heal_amt = BASE_HEAL_PLASMA_FIXATION * actual_power if(prob(5)) to_chat(M, span_notice("You feel yourself absorbing plasma inside and around you...")) @@ -549,6 +594,11 @@ ///Plasma End #undef HEALING_PER_MOL +#undef HEALING_PER_BREATH_PRESSURE +#undef MAX_HEAL_COEFFICIENT_INTERNALS +#undef MAX_HEAL_COEFFICIENT_ENVIRONMENT +#undef MAX_HEAL_COEFFICIENT_BLOODSTREAM +#undef BASE_HEAL_PLASMA_FIXATION /datum/symptom/heal/radiation name = "Radioactive Resonance" diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm index 03fec110ac2..bb279178f05 100644 --- a/code/game/machinery/dna_infuser/dna_infuser.dm +++ b/code/game/machinery/dna_infuser/dna_infuser.dm @@ -127,7 +127,7 @@ for(var/obj/item/organ/new_organ in infusing_into.output_organs) var/obj/item/organ/old_organ = target.getorganslot(initial(new_organ.slot)) if(old_organ) - if((old_organ.type != new_organ) && (old_organ.status == ORGAN_ORGANIC)) + if((old_organ.type != new_organ) && (old_organ.status != ORGAN_ROBOTIC)) continue // Old organ can be mutated! else if(isexternalorgan(new_organ)) continue // External organ can be grown! diff --git a/code/modules/antagonists/heretic/heretic_living_heart.dm b/code/modules/antagonists/heretic/heretic_living_heart.dm index 4dda1a2f73a..063303c49b6 100644 --- a/code/modules/antagonists/heretic/heretic_living_heart.dm +++ b/code/modules/antagonists/heretic/heretic_living_heart.dm @@ -55,7 +55,7 @@ /datum/component/living_heart/proc/on_organ_replaced(obj/item/organ/source, obj/item/organ/replacement) SIGNAL_HANDLER - if(replacement.status != ORGAN_ORGANIC || (replacement.organ_flags & ORGAN_SYNTHETIC)) + if(replacement.status == ORGAN_ROBOTIC || (replacement.organ_flags & ORGAN_SYNTHETIC)) qdel(src) return diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index 65f5bc8201d..deb2deacb52 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -183,7 +183,7 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) return FALSE if(!new_heart.useable) return FALSE - if(new_heart.status != ORGAN_ORGANIC) + if(new_heart.status == ORGAN_ROBOTIC) return FALSE if(new_heart.organ_flags & (ORGAN_SYNTHETIC|ORGAN_FAILING)) return FALSE diff --git a/code/modules/antagonists/heretic/structures/mawed_crucible.dm b/code/modules/antagonists/heretic/structures/mawed_crucible.dm index a409c38d1b9..1b720cd9940 100644 --- a/code/modules/antagonists/heretic/structures/mawed_crucible.dm +++ b/code/modules/antagonists/heretic/structures/mawed_crucible.dm @@ -84,7 +84,7 @@ if(isorgan(weapon)) var/obj/item/organ/consumed = weapon - if(consumed.status != ORGAN_ORGANIC || (consumed.organ_flags & ORGAN_SYNTHETIC)) + if(consumed.status == ORGAN_ROBOTIC || (consumed.organ_flags & ORGAN_SYNTHETIC)) balloon_alert(user, "not organic!") return if(consumed.organ_flags & ORGAN_VITAL) // Basically, don't eat organs like brains diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 93ef929ce36..14c72099a02 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -136,12 +136,11 @@ /datum/species/plasmaman/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, delta_time, times_fired) . = ..() - if(istype(chem, /datum/reagent/toxin/plasma)) - H.reagents.remove_reagent(chem.type, chem.metabolization_rate * delta_time) + if(istype(chem, /datum/reagent/toxin/plasma) || istype(chem, /datum/reagent/toxin/hot_ice)) for(var/i in H.all_wounds) var/datum/wound/iter_wound = i iter_wound.on_xadone(4 * REAGENTS_EFFECT_MULTIPLIER * delta_time) // plasmamen use plasma to reform their bones or whatever - return TRUE + return FALSE // do normal metabolism if(istype(chem, /datum/reagent/toxin/bonehurtingjuice)) H.adjustStaminaLoss(7.5 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 0) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index e16216b4edd..0bfbffc0a70 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -105,6 +105,13 @@ affected_mob.adjustPlasma(20 * REM * delta_time) return ..() +/datum/reagent/toxin/plasma/on_mob_metabolize(mob/living/carbon/affected_mob) + if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM)) // sometimes mobs can temporarily metabolize plasma (e.g. plasma fixation disease symptom) + toxpwr = 0 + +/datum/reagent/toxin/plasma/on_mob_end_metabolize(mob/living/carbon/affected_mob) + toxpwr = initial(toxpwr) + /// Handles plasma boiling. /datum/reagent/toxin/plasma/proc/on_temp_change(datum/reagents/_holder, old_temp) SIGNAL_HANDLER @@ -153,6 +160,13 @@ humi.adjust_coretemperature(-7 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * delta_time, affected_mob.get_body_temp_normal()) return ..() +/datum/reagent/toxin/hot_ice/on_mob_metabolize(mob/living/carbon/affected_mob) + if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM)) + toxpwr = 0 + +/datum/reagent/toxin/hot_ice/on_mob_end_metabolize(mob/living/carbon/affected_mob) + toxpwr = initial(toxpwr) + /datum/reagent/toxin/lexorin name = "Lexorin" description = "A powerful poison used to stop respiration." diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index c7b7f148126..50562c28b35 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -107,6 +107,8 @@ if(filterToxins && !HAS_TRAIT(liver_owner, TRAIT_TOXINLOVER)) for(var/datum/reagent/toxin/toxin in cached_reagents) + if(status != toxin.affected_organtype) //this particular toxin does not affect this type of organ + continue var/amount = round(toxin.volume, CHEMICAL_QUANTISATION_LEVEL) // this is an optimization if(belly) amount += belly.reagents.get_reagent_amount(toxin.type) @@ -217,6 +219,7 @@ name = "reagent processing crystal" icon_state = "liver-p" desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen." + status = ORGAN_MINERAL // alien livers can ignore up to 15u of toxins, but they take x3 liver damage /obj/item/organ/internal/liver/alien