diff --git a/code/modules/admin/reagents_editor.dm b/code/modules/admin/reagents_editor.dm index 1cce2d8ebba..bacd09be224 100644 --- a/code/modules/admin/reagents_editor.dm +++ b/code/modules/admin/reagents_editor.dm @@ -70,8 +70,10 @@ reagent = new reagent_prototype.type() reagent.holder = target.reagents reagent.on_new() - if(ishuman(target) && target.reagents.can_metabolize(target, reagent)) - reagent.on_mob_add(target) + if(ishuman(target)) + var/mob/living/carbon/human/human = target + if(human.can_metabolize(reagent)) + reagent.on_mob_add(human) target.reagents.reagent_list += reagent reagent.volume = new_volume diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm index 26b197f3cd0..5e1aa482519 100644 --- a/code/modules/mob/living/carbon/carbon_procs.dm +++ b/code/modules/mob/living/carbon/carbon_procs.dm @@ -1113,12 +1113,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven return TRUE /mob/living/carbon/proc/shock_reduction() - var/shock_reduction = 0 - if(reagents) - for(var/datum/reagent/R in reagents.reagent_list) - if(R.shock_reduction) - shock_reduction += R.shock_reduction - return shock_reduction + return 0 /mob/living/carbon/proc/can_eat(flags = 255) return TRUE diff --git a/code/modules/mob/living/carbon/human/human_life.dm b/code/modules/mob/living/carbon/human/human_life.dm index 83785afae09..0888e801bdd 100644 --- a/code/modules/mob/living/carbon/human/human_life.dm +++ b/code/modules/mob/living/carbon/human/human_life.dm @@ -689,60 +689,83 @@ to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!") Weaken(6 SECONDS) +/mob/living/carbon/human/proc/can_metabolize(datum/reagent/reagent) + var/datum/species/species = dna.species + if(!species || !species.reagent_tag) + return FALSE + + // SYNTHETIC-oriented reagents require PROCESS_SYN + if((reagent.process_flags & SYNTHETIC) && (species.reagent_tag & PROCESS_SYN)) + return TRUE + + // ORGANIC-oriented reagents require PROCESS_ORG + if((reagent.process_flags & ORGANIC) && (species.reagent_tag & PROCESS_ORG)) + return TRUE + + // Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater + if((reagent.process_flags & ORGANIC) && (reagent.process_flags & SYNTHETIC) && (species.reagent_tag & PROCESS_DUO)) + return TRUE + return FALSE + +/mob/living/carbon/human/shock_reduction() + var/shock_reduction = 0 + if(reagents) + for(var/datum/reagent/R in reagents.reagent_list) + if(R.shock_reduction && can_metabolize(R)) + shock_reduction += R.shock_reduction + return shock_reduction + #define BODYPART_PAIN_REDUCTION 5 /mob/living/carbon/human/update_health_hud() if(!client) return - if(dna.species.update_health_hud()) - return - else - var/shock_reduction = shock_reduction() - if(healths) - var/health_amount = get_perceived_trauma(shock_reduction) - if(..(health_amount)) //not dead - switch(health_hud_override) - if(HEALTH_HUD_OVERRIDE_CRIT) - healths.icon_state = "health6" - if(HEALTH_HUD_OVERRIDE_DEAD) - healths.icon_state = "health7" - if(HEALTH_HUD_OVERRIDE_HEALTHY) - healths.icon_state = "health0" + var/shock_reduction = shock_reduction() + if(healths) + var/health_amount = get_perceived_trauma(shock_reduction) + if(..(health_amount)) //not dead + switch(health_hud_override) + if(HEALTH_HUD_OVERRIDE_CRIT) + healths.icon_state = "health6" + if(HEALTH_HUD_OVERRIDE_DEAD) + healths.icon_state = "health7" + if(HEALTH_HUD_OVERRIDE_HEALTHY) + healths.icon_state = "health0" - if(healthdoll) - if(stat == DEAD) - healthdoll.icon_state = "healthdoll_DEAD" - if(length(healthdoll.overlays)) - healthdoll.overlays.Cut() - else - var/list/new_overlays = list() - var/list/cached_overlays = healthdoll.cached_healthdoll_overlays - // Use the dead health doll as the base, since we have proper "healthy" overlays now - healthdoll.icon_state = "healthdoll_DEAD" - for(var/obj/item/organ/external/O in bodyparts) - var/damage = O.get_damage() - damage -= shock_reduction / BODYPART_PAIN_REDUCTION - var/comparison = (O.max_damage/5) - var/icon_num = 0 - if(damage > 0) - icon_num = 1 - if(damage > (comparison)) - icon_num = 2 - if(damage > (comparison*2)) - icon_num = 3 - if(damage > (comparison*3)) - icon_num = 4 - if(damage > (comparison*4)) - icon_num = 5 - new_overlays += "[O.limb_name][icon_num]" - healthdoll.overlays += (new_overlays - cached_overlays) - healthdoll.overlays -= (cached_overlays - new_overlays) - healthdoll.cached_healthdoll_overlays = new_overlays - - if(health <= HEALTH_THRESHOLD_SUCCUMB) - throw_alert("succumb", /atom/movable/screen/alert/succumb) + if(healthdoll) + if(stat == DEAD) + healthdoll.icon_state = "healthdoll_DEAD" + if(length(healthdoll.overlays)) + healthdoll.overlays.Cut() else - clear_alert("succumb") + var/list/new_overlays = list() + var/list/cached_overlays = healthdoll.cached_healthdoll_overlays + // Use the dead health doll as the base, since we have proper "healthy" overlays now + healthdoll.icon_state = "healthdoll_DEAD" + for(var/obj/item/organ/external/O in bodyparts) + var/damage = O.get_damage() + damage -= shock_reduction / BODYPART_PAIN_REDUCTION + var/comparison = (O.max_damage/5) + var/icon_num = 0 + if(damage > 0) + icon_num = 1 + if(damage > (comparison)) + icon_num = 2 + if(damage > (comparison*2)) + icon_num = 3 + if(damage > (comparison*3)) + icon_num = 4 + if(damage > (comparison*4)) + icon_num = 5 + new_overlays += "[O.limb_name][icon_num]" + healthdoll.overlays += (new_overlays - cached_overlays) + healthdoll.overlays -= (cached_overlays - new_overlays) + healthdoll.cached_healthdoll_overlays = new_overlays + + if(health <= HEALTH_THRESHOLD_SUCCUMB) + throw_alert("succumb", /atom/movable/screen/alert/succumb) + else + clear_alert("succumb") #undef BODYPART_PAIN_REDUCTION diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index cb71257554d..b4852e6f30b 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -349,10 +349,8 @@ leftover -= . var/health_deficiency = max(H.maxHealth - H.health, H.getStaminaLoss()) - if(H.reagents) - for(var/datum/reagent/R in H.reagents.reagent_list) - if(R.shock_reduction) - health_deficiency -= R.shock_reduction + health_deficiency -= H.shock_reduction() + if(HAS_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN)) return if(health_deficiency >= 40 - (40 * leftover * SLOWDOWN_MULTIPLIER)) //If we have 0.25 slowdown, or halfway to the threshold of 0.5, we reduce the health threshold by that 50% @@ -918,9 +916,6 @@ return FALSE //Unsupported slot -/datum/species/proc/update_health_hud(mob/living/carbon/human/H) - return FALSE - /datum/species/proc/handle_mutations_and_radiation(mob/living/carbon/human/H) if(HAS_TRAIT(H, TRAIT_RADIMMUNE)) H.radiation = 0 diff --git a/code/modules/reagents/chemistry/reagents_holder.dm b/code/modules/reagents/chemistry/reagents_holder.dm index 2e108970e3c..e5e9780c74a 100644 --- a/code/modules/reagents/chemistry/reagents_holder.dm +++ b/code/modules/reagents/chemistry/reagents_holder.dm @@ -290,16 +290,6 @@ R.handle_reactions() return amount -/datum/reagents/proc/can_metabolize(mob/living/carbon/human/H, datum/reagent/R) - if(!H.dna.species || !H.dna.species.reagent_tag) - return FALSE - if((R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN - return TRUE - if((R.process_flags & ORGANIC) && (H.dna.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG - return TRUE - //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) - return TRUE /** * Called by `/mob/living/proc/Life`. You shouldn't have to use this one directly. @@ -327,7 +317,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M //Check if this mob's species is set and can process this type of reagent - var/can_process = can_metabolize(H, R) + var/can_process = H.can_metabolize(R) //If handle_reagents returns 0, it's doing the reagent removal on its own var/species_handled = !(H.dna.species.handle_reagents(H, R)) can_process = can_process && !species_handled @@ -559,9 +549,10 @@ for(var/A in cached_reagents) var/datum/reagent/R = A if(R.id == reagent) - if(ishuman(my_atom) && can_metabolize(my_atom, R)) - var/mob/living/carbon/human/M = my_atom - R.on_mob_delete(M) + if(ishuman(my_atom)) + var/mob/living/carbon/human/human = my_atom + if(human.can_metabolize(R)) + R.on_mob_delete(human) cached_reagents -= A qdel(A) update_total() @@ -714,13 +705,13 @@ var/datum/reagent/D = GLOB.chemical_reagents_list[reagent] if(D) - var/datum/reagent/R = new D.type() cached_reagents += R R.holder = src R.volume = amount if(ishuman(my_atom)) - if(can_metabolize(my_atom, R)) + var/mob/living/carbon/human/human = my_atom + if(human.can_metabolize(R)) R.on_new(data) else R.on_new(data) @@ -728,11 +719,15 @@ if(data) R.data = data - if(ishuman(my_atom) && can_metabolize(my_atom, R)) - R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + if(ishuman(my_atom)) + var/mob/living/carbon/human/human = my_atom + if(human.can_metabolize(R)) + R.on_mob_add(my_atom) //Must occur before it could posibly run on_mob_delete + update_total() if(my_atom) my_atom.on_reagent_change() + if(!no_react) temperature_react() handle_reactions()