diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 6cb99a58e17..88cccd3115f 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -562,7 +562,6 @@ desc = "You can't get enough of hard drugs." value = -2 gain_text = "You suddenly feel the craving for drugs." - lose_text = "You feel like you should kick your drug habit." medical_record_text = "Patient has a history of hard drugs." hardcore_value = 4 var/drug_list = list(/datum/reagent/drug/crank, /datum/reagent/drug/krokodil, /datum/reagent/medicine/morphine, /datum/reagent/drug/happiness, /datum/reagent/drug/methamphetamine) //List of possible IDs @@ -610,15 +609,22 @@ var/mob/living/carbon/human/H = quirk_holder SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_SHOW, H) +/datum/quirk/junkie/remove() + if(quirk_holder && reagent_instance) + quirk_holder.reagents.remove_addiction(reagent_instance) //chat feedback here. No need of lose_text. + /datum/quirk/junkie/proc/announce_drugs() to_chat(quirk_holder, "There is a [initial(drug_container_type.name)] of [initial(reagent_type.name)] [where_drug]. Better hope you don't run out...") /datum/quirk/junkie/on_process() + if(HAS_TRAIT(quirk_holder, TRAIT_NOMETABOLISM)) + return var/mob/living/carbon/human/H = quirk_holder if(world.time > next_process) next_process = world.time + process_interval - if(!H.reagents.addiction_list.Find(reagent_instance)) - if(QDELETED(reagent_instance)) + var/deleted = QDELETED(reagent_instance) + if(deleted || !LAZYFIND(H.reagents.addiction_list, reagent_instance)) + if(deleted) reagent_instance = new reagent_type() else reagent_instance.addiction_stage = 0 @@ -630,7 +636,6 @@ desc = "Sometimes you just really want a smoke. Probably not great for your lungs." value = -1 gain_text = "You could really go for a smoke right about now." - lose_text = "You feel like you should quit smoking." medical_record_text = "Patient is a current smoker." reagent_type = /datum/reagent/drug/nicotine accessory_type = /obj/item/lighter/greyscale diff --git a/code/modules/mob/living/carbon/init_signals.dm b/code/modules/mob/living/carbon/init_signals.dm index 75e47d5ba4e..4bd32b22a73 100644 --- a/code/modules/mob/living/carbon/init_signals.dm +++ b/code/modules/mob/living/carbon/init_signals.dm @@ -3,6 +3,7 @@ . = ..() RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_NOBREATH), .proc/on_nobreath_trait_gain) + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_NOMETABOLISM), .proc/on_nometabolism_trait_gain) /** * On gain of TRAIT_NOBREATH @@ -10,6 +11,8 @@ * This will clear all alerts and moods related to breathing. */ /mob/living/carbon/proc/on_nobreath_trait_gain(datum/source) + SIGNAL_HANDLER + failed_last_breath = FALSE clear_alert("too_much_oxy") clear_alert("not_enough_oxy") @@ -23,3 +26,19 @@ SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation") +/** + * On gain of TRAIT_NOMETABOLISM + * + * This will clear all moods related to addictions and stop metabolization. + */ +/mob/living/carbon/proc/on_nometabolism_trait_gain(datum/source) + SIGNAL_HANDLER + + if(reagents.addiction_list) + to_chat(source, "You feel like you've gotten over your need for drugs.") + for(var/a in reagents.addiction_list) + var/datum/reagent/R = a + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_overdose") + LAZYREMOVE(reagents.addiction_list, R) + qdel(R) + reagents.end_metabolization(keep_liverless = TRUE) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index b0a180179d9..30cbf29aa92 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -63,7 +63,7 @@ /// see [/datum/reagents/proc/metabolize] for usage var/addiction_tick = 1 /// currently addicted reagents - var/list/datum/reagent/addiction_list = new/list() + var/list/datum/reagent/addiction_list /// various flags, see code\__DEFINES\reagents.dm var/flags @@ -81,13 +81,11 @@ /datum/reagents/Destroy() . = ..() //We're about to delete all reagents, so lets cleanup - addiction_list.Cut() - var/list/cached_reagents = reagent_list - for(var/reagent in cached_reagents) + addiction_list = null + for(var/reagent in reagent_list) var/datum/reagent/R = reagent qdel(R) - cached_reagents.Cut() - cached_reagents = null + reagent_list = null if(my_atom && my_atom.reagents == src) my_atom.reagents = null my_atom = null @@ -413,15 +411,17 @@ R.overdosed = TRUE need_mob_update += R.overdose_start(C) log_game("[key_name(C)] has started overdosing on [R.name] at [R.volume] units.") + var/is_addicted_to = cached_addictions && is_type_in_list(R, cached_addictions) if(R.addiction_threshold) - if(R.volume >= R.addiction_threshold && !is_type_in_list(R, cached_addictions)) + if(R.volume >= R.addiction_threshold && !is_addicted_to) var/datum/reagent/new_reagent = new R.addiction_type() - cached_addictions.Add(new_reagent) + LAZYADD(cached_addictions, new_reagent) + is_addicted_to = TRUE log_game("[key_name(C)] has become addicted to [R.name] at [R.volume] units.") if(R.overdosed) need_mob_update += R.overdose_process(C) var/datum/reagent/addiction_type = new R.addiction_type() - if(is_type_in_list(addiction_type ,cached_addictions)) + if(is_addicted_to) for(var/addiction in cached_addictions) var/datum/reagent/A = addiction if(istype(addiction_type, A)) @@ -433,21 +433,22 @@ addiction_tick = 1 for(var/addiction in cached_addictions) var/datum/reagent/R = addiction - if(C && R) - R.addiction_stage++ - switch(R.addiction_stage) - if(1 to 10) - need_mob_update += R.addiction_act_stage1(C) - if(10 to 20) - need_mob_update += R.addiction_act_stage2(C) - if(20 to 30) - need_mob_update += R.addiction_act_stage3(C) - if(30 to 40) - need_mob_update += R.addiction_act_stage4(C) - if(40 to INFINITY) - remove_addiction(R) - else - SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_overdose") + if(!C) + break + R.addiction_stage++ + switch(R.addiction_stage) + if(1 to 10) + need_mob_update += R.addiction_act_stage1(C) + if(10 to 20) + need_mob_update += R.addiction_act_stage2(C) + if(20 to 30) + need_mob_update += R.addiction_act_stage3(C) + if(30 to 40) + need_mob_update += R.addiction_act_stage4(C) + if(40 to INFINITY) + remove_addiction(R) + else + SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_overdose") addiction_tick++ if(C && need_mob_update) //some of the metabolized reagents had effects on the mob that requires some updates. C.updatehealth() @@ -458,7 +459,7 @@ /datum/reagents/proc/remove_addiction(datum/reagent/R) to_chat(my_atom, "You feel like you've gotten over your need for [R.name].") SEND_SIGNAL(my_atom, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_overdose") - addiction_list.Remove(R) + LAZYREMOVE(addiction_list, R) qdel(R) /// Signals that metabolization has stopped, triggering the end of trait-based effects @@ -643,7 +644,7 @@ R.on_mob_delete(my_atom) //Clear from relevant lists - addiction_list -= R + LAZYREMOVE(addiction_list, R) reagent_list -= R qdel(R) update_total()