Skip to content

Commit

Permalink
[MIRROR] Adds on_mob_life SHOULD_CALL_PARENT, fixes holy water me…
Browse files Browse the repository at this point in the history
…tabolizing at double rate [MDB IGNORE] (#24309)

* Adds `on_mob_life` `SHOULD_CALL_PARENT`, fixes holy water metabolizing at double rate (#78932)

## About The Pull Request

- Fixes #78919

- Adds `SHOULD_CALL_PARENT` to reagent `on_mob_life`, fixes a few places
which didn't call parent

- Off the top of my head I remembered holy water purposefully didn't
call parent to get a static metabolism rate. However #78657 added a
parent call to holy water, meaning it's been metabolizing out twice,
incredibly fast. Fixes that.

## Why It's Good For The Game

Reagent parent is fairly important as it handles removing the reagent
from the mob.

## Changelog

:cl: Melbert
fix: Fixes Mauna Loa, Monover, Silibinin, Granibitaluri not exiting your
system on metabolism
fix: Fixes holy water exiting your system at double the rate on
metabolism
fix: Holy Water no longer spams cultists with big text every time, it's
much more tame now
/:cl:

* Adds `on_mob_life` `SHOULD_CALL_PARENT`, fixes holy water metabolizing at double rate

---------

Co-authored-by: MrMelbert <[email protected]>
  • Loading branch information
2 people authored and Iajret committed Oct 13, 2023
1 parent 3ab93db commit 0e02883
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 55 deletions.
7 changes: 7 additions & 0 deletions code/__DEFINES/reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@
#define REAGENT_CLEANS (1<<8)
///Does this reagent affect wounds? Used to check if some procs should be ran.
#define REAGENT_AFFECTS_WOUNDS (1<<9)
/// If present, when metabolizing out of a mob, we divide by the mob's metabolism rather than multiply.
/// Without this flag: Higher metabolism means the reagent exits the system faster.
/// With this flag: Higher metabolism means the reagent exits the system slower.
#define REAGENT_REVERSE_METABOLISM (1<<10)
/// If present, this reagent will not be affected by the mob's metabolism at all, meaning it exits at a fixed rate for all mobs.
/// Supercedes [REAGENT_REVERSE_METABOLISM].
#define REAGENT_UNAFFECTED_BY_METABOLISM (1<<11)

//Chemical reaction flags, for determining reaction specialties
///Convert into impure/pure on reaction completion
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@
var/datum/reagent/bits = bile
if(istype(bits, /datum/reagent/consumable))
var/datum/reagent/consumable/goodbit = bile
fullness += goodbit.get_nutriment_factor() * goodbit.volume / goodbit.metabolization_rate
fullness += goodbit.get_nutriment_factor(src) * goodbit.volume / goodbit.metabolization_rate
continue
fullness += 0.6 * bits.volume / bits.metabolization_rate //not food takes up space

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
for(var/bile in reagents.reagent_list)
var/datum/reagent/consumable/bits = bile
if(bits)
fullness += bits.get_nutriment_factor() * bits.volume / bits.metabolization_rate
fullness += bits.get_nutriment_factor(src) * bits.volume / bits.metabolization_rate
return fullness

/**
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/simple_animal/hostile/ooze.dm
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
var/consumption_amount = min(reagents.get_reagent_amount(reagent.type), ooze_metabolism_modifier * REAGENTS_METABOLISM * seconds_per_tick)
if(istype(reagent, /datum/reagent/consumable))
var/datum/reagent/consumable/consumable = reagent
nutrition_change += consumption_amount * consumable.get_nutriment_factor()
nutrition_change += consumption_amount * consumable.get_nutriment_factor(src)
reagents.remove_reagent(reagent.type, consumption_amount)
adjust_ooze_nutrition(nutrition_change)

Expand Down
14 changes: 12 additions & 2 deletions code/modules/reagents/chemistry/reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,21 @@
*
*/
/datum/reagent/proc/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
SHOULD_CALL_PARENT(TRUE)
current_cycle++
if(length(reagent_removal_skip_list))
return
if(holder)
holder.remove_reagent(type, metabolization_rate * affected_mob.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears.
if(isnull(holder))
return

var/metabolizing_out = metabolization_rate * seconds_per_tick
if(!(chemical_flags & REAGENT_UNAFFECTED_BY_METABOLISM))
if(chemical_flags & REAGENT_REVERSE_METABOLISM)
metabolizing_out /= affected_mob.metabolism_efficiency
else
metabolizing_out *= affected_mob.metabolism_efficiency

holder.remove_reagent(type, metabolizing_out)

/// Called in burns.dm *if* the reagent has the REAGENT_AFFECTS_WOUNDS process flag
/datum/reagent/proc/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED

/datum/reagent/consumable/ethanol/mauna_loa/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
. = ..()
// Heats the user up while the reagent is in the body. Occasionally makes you burst into flames.
drinker.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick)
if (SPT_PROB(2.5, seconds_per_tick))
Expand Down
38 changes: 19 additions & 19 deletions code/modules/reagents/chemistry/reagents/food_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@
/// affects mood, typically higher for mixed drinks with more complex recipes'
var/quality = 0

/datum/reagent/consumable/New()
. = ..()
// All food reagents function at a fixed rate
chemical_flags |= REAGENT_UNAFFECTED_BY_METABOLISM

/datum/reagent/consumable/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
current_cycle++
if(ishuman(affected_mob))
var/mob/living/carbon/human/affected_human = affected_mob
if(!HAS_TRAIT(affected_human, TRAIT_NOHUNGER))
affected_human.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick)
if(length(reagent_removal_skip_list))
. = ..()
if(!ishuman(affected_mob) || HAS_TRAIT(affected_mob, TRAIT_NOHUNGER))
return
if(holder)
holder.remove_reagent(type, metabolization_rate * seconds_per_tick)

var/mob/living/carbon/human/affected_human = affected_mob
affected_human.adjust_nutrition(get_nutriment_factor(affected_mob) * REM * seconds_per_tick)

/datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
Expand Down Expand Up @@ -57,8 +59,9 @@
exposed_mob.add_mood_event("quality_drink", /datum/mood_event/race_drink)
// SKYRAT ADDITION END

/datum/reagent/consumable/proc/get_nutriment_factor()
return nutriment_factor * REAGENTS_METABOLISM * (purity * 2)
/// Gets just how much nutrition this reagent is worth for the passed mob
/datum/reagent/consumable/proc/get_nutriment_factor(mob/living/carbon/eater)
return nutriment_factor * REAGENTS_METABOLISM * purity * 2

/datum/reagent/consumable/nutriment
name = "Nutriment"
Expand Down Expand Up @@ -261,15 +264,12 @@
brute_heal = 0
burn_heal = 0

/datum/reagent/consumable/nutriment/mineral/on_mob_life(mob/living/carbon/eater, seconds_per_tick, times_fired)
if(HAS_TRAIT(eater, TRAIT_ROCK_EATER)) // allow mobs who can eat rocks to do so
/datum/reagent/consumable/nutriment/mineral/get_nutriment_factor(mob/living/carbon/eater)
if(HAS_TRAIT(eater, TRAIT_ROCK_EATER))
return ..()
else // otherwise just let them pass through the system
current_cycle++
if(length(reagent_removal_skip_list))
return
if(holder)
holder.remove_reagent(type, metabolization_rate * seconds_per_tick)

// You cannot eat rocks, it gives no nutrition
return 0

/datum/reagent/consumable/sugar
name = "Sugar"
Expand Down Expand Up @@ -876,7 +876,7 @@
/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(affected_mob.nutrition > NUTRITION_LEVEL_FULL - 25)
affected_mob.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick)
affected_mob.adjust_nutrition(-3 * REM * get_nutriment_factor(affected_mob) * seconds_per_tick)

////Lavaland Flora Reagents////

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ Basically, we fill the time between now and 2s from now with hands based off the

//Heals toxins if it's the only thing present - kinda the oposite of multiver! Maybe that's why it's inverse!
/datum/reagent/inverse/healing/monover/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
var/need_mob_update
if(length(affected_mob.reagents.reagent_list) > 1)
need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * seconds_per_tick, required_organ_flag = affected_organ_flags) //Hey! It's everyone's favourite drawback from multiver!
Expand Down
12 changes: 6 additions & 6 deletions code/modules/reagents/chemistry/reagents/medicine_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
/datum/reagent/medicine
taste_description = "bitterness"

/datum/reagent/medicine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
current_cycle++
if(length(reagent_removal_skip_list))
return
if(holder)
holder.remove_reagent(type, metabolization_rate * seconds_per_tick / affected_mob.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism
/datum/reagent/medicine/New()
. = ..()
// All medicine metabolizes out slower / stay longer if you have a better metabolism
chemical_flags |= REAGENT_REVERSE_METABOLISM

/datum/reagent/medicine/leporazine
name = "Leporazine"
Expand Down Expand Up @@ -1620,6 +1618,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED

/datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) // Add a chance to cure liver trauma once implemented.
return UPDATE_MOB_HEALTH

Expand Down Expand Up @@ -1664,6 +1663,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED

/datum/reagent/medicine/granibitaluri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
var/healamount = max(0.5 - round(0.01 * (affected_mob.getBruteLoss() + affected_mob.getFireLoss()), 0.1), 0) //base of 0.5 healing per cycle and loses 0.1 healing for every 10 combined brute/burn damage you have
var/need_mob_update
need_mob_update = affected_mob.adjustBruteLoss(-healamount * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
Expand Down
55 changes: 30 additions & 25 deletions code/modules/reagents/chemistry/reagents/other_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@
color = "#E0E8EF" // rgb: 224, 232, 239
self_consuming = TRUE //divine intervention won't be limited by the lack of a liver
ph = 7.5 //God is alkaline
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS|REAGENT_UNAFFECTED_BY_METABOLISM // Operates at fixed metabolism for balancing memes.
default_container = /obj/item/reagent_containers/cup/glass/bottle/holywater

/datum/glass_style/drinking_glass/holywater
Expand All @@ -364,6 +364,15 @@
desc = "A glass of holy water."
icon_state = "glass_clear"

/datum/reagent/water/holywater/on_new(list/data)
// Tracks the total amount of deciseconds that the reagent has been metab'd for, for the purpose of deconversion
if(isnull(data))
data = list("deciseconds_metabolized" = 0)
else if(isnull(data["deciseconds_metabolized"]))
data["deciseconds_metabolized"] = 0

return ..()

// Holy water. Unlike water, which is nuked, stays in and heals the plant a little with the power of the spirits. Also ALSO increases instability.
/datum/reagent/water/holywater/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.adjust_waterlevel(round(volume))
Expand All @@ -374,53 +383,49 @@
. = ..()
ADD_TRAIT(affected_mob, TRAIT_HOLY, type)

/datum/reagent/water/holywater/on_mob_add(mob/living/affected_mob, amount)
. = ..()
if(data)
data["misc"] = 0

/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
REMOVE_TRAIT(affected_mob, TRAIT_HOLY, type)

/datum/reagent/water/holywater/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
/datum/reagent/water/holywater/on_mob_add(mob/living/affected_mob, amount)
. = ..()
if(IS_CULTIST(exposed_mob))
to_chat(exposed_mob, span_userdanger("A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!"))
if(IS_CULTIST(affected_mob))
to_chat(affected_mob, span_userdanger("A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!"))

/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(!data)
data = list("misc" = 0)

data["misc"] += seconds_per_tick SECONDS * REM
affected_mob.adjust_jitter_up_to(4 SECONDS * seconds_per_tick, 20 SECONDS)
data["deciseconds_metabolized"] += (seconds_per_tick * 1 SECONDS * REM)

affected_mob.adjust_jitter_up_to(4 SECONDS * REM * seconds_per_tick, 20 SECONDS)

if(IS_CULTIST(affected_mob))
for(var/datum/action/innate/cult/blood_magic/BM in affected_mob.actions)
to_chat(affected_mob, span_cultlarge("Your blood rites falter as holy water scours your body!"))
var/removed_any = FALSE
for(var/datum/action/innate/cult/blood_spell/BS in BM.spells)
removed_any = TRUE
qdel(BS)
if(data["misc"] >= (25 SECONDS)) // 10 units
affected_mob.adjust_stutter_up_to(4 SECONDS * seconds_per_tick, 20 SECONDS)
if(removed_any)
to_chat(affected_mob, span_cultlarge("Your blood rites falter as holy water scours your body!"))

if(data["deciseconds_metabolized"] >= (25 SECONDS)) // 10 units
affected_mob.adjust_stutter_up_to(4 SECONDS * REM * seconds_per_tick, 20 SECONDS)
affected_mob.set_dizzy_if_lower(10 SECONDS)
if(IS_CULTIST(affected_mob) && SPT_PROB(10, seconds_per_tick))
affected_mob.say(pick("Av'te Nar'Sie","Pa'lid Mors","INO INO ORA ANA","SAT ANA!","Daim'niodeis Arc'iai Le'eones","R'ge Na'sie","Diabo us Vo'iscum","Eld' Mon Nobis"), forced = "holy water")
if(prob(10))
affected_mob.visible_message(span_danger("[affected_mob] starts having a seizure!"), span_userdanger("You have a seizure!"))
affected_mob.Unconscious(12 SECONDS)
to_chat(affected_mob, "<span class='cultlarge'>[pick("Your blood is your bond - you are nothing without it", "Do not forget your place", \
"All that power, and you still fail?", "If you cannot scour this poison, I shall scour your meager life!")].</span>")
if(data["misc"] >= (1 MINUTES)) // 24 units
to_chat(affected_mob, span_cultlarge("[pick("Your blood is your bond - you are nothing without it", "Do not forget your place", \
"All that power, and you still fail?", "If you cannot scour this poison, I shall scour your meager life!")]."))

if(data["deciseconds_metabolized"] >= (1 MINUTES)) // 24 units
if(IS_CULTIST(affected_mob))
affected_mob.mind.remove_antag_datum(/datum/antagonist/cult)
affected_mob.Unconscious(100)
affected_mob.Unconscious(10 SECONDS)
affected_mob.remove_status_effect(/datum/status_effect/jitter)
affected_mob.remove_status_effect(/datum/status_effect/speech/stutter)
if(holder)
holder.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
return
if(holder)
holder.remove_reagent(type, 1 * REAGENTS_METABOLISM * seconds_per_tick) //fixed consumption to prevent balancing going out of whack
holder?.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??

/datum/reagent/water/holywater/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
Expand Down

0 comments on commit 0e02883

Please sign in to comment.