Files
+37 21b4095dfd [MDB IGNORE] [IDB IGNORE] Upstream Sync - 04/17/2026 (#5453)
Upstream 04/17/2026

fixes https://github.com/Bubberstation/Bubberstation/issues/5549

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com>
Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com>
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com>
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com>
Co-authored-by: loganuk <fakeemail123@aol.com>
Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com>
Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com>
Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com>
Co-authored-by: Lucy <lucy@absolucy.moe>
Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com>
Co-authored-by: Isratosh <Isratosh@hotmail.com>
Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com>
Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com>
Co-authored-by: Alexander V. <volas@ya.ru>
Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com>
Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Tim <timothymtorres@gmail.com>
Co-authored-by: Iamgoofball <iamgoofball@gmail.com>
Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com>
Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com>
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com>
Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com>
Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com>
Co-authored-by: Josh <josh.adam.powell@gmail.com>
Co-authored-by: Josh Powell <josh.powell@softwire.com>
Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com>
Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com>
Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com>
Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
2026-05-16 00:56:00 +02:00

149 lines
7.2 KiB
Plaintext

GLOBAL_LIST_INIT_TYPED(addictions, /datum/addiction, init_subtypes_w_path_keys(/datum/addiction))
///base class for addiction, handles when you become addicted and what the effects of that are. By default you become addicted when you hit a certain threshold, and stop being addicted once you go below another one.
/datum/addiction
///Name of this addiction
var/name = "cringe code"
///Description of this addiction
var/description = "A harmful dependence on cringe code."
///Medical symptoms of this addiction
var/symptoms = "Wants more cringe code."
///Higher threshold, when you start being addicted
var/addiction_gain_threshold = 600
///Lower threshold, when you stop being addicted
var/addiction_loss_threshold = 400
///Messages for each stage of addictions.
var/list/withdrawal_stage_messages = list()
///Rates at which you lose addiction (in units/second) if you are not on the drug at that time per stage
var/addiction_loss_per_stage = list(0.5, 0.5, 1, 1.5)
///Rate at which high sanity helps addiction loss
var/high_sanity_addiction_loss = 2
///Amount of drugs you need in your system to be satisfied
var/addiction_relief_treshold = MIN_ADDICTION_REAGENT_AMOUNT
///moodlet for light withdrawal
var/light_withdrawal_moodlet = /datum/mood_event/withdrawal_light
///moodlet for medium withdrawal
var/medium_withdrawal_moodlet = /datum/mood_event/withdrawal_medium
///moodlet for severe withdrawal
var/severe_withdrawal_moodlet = /datum/mood_event/withdrawal_severe
///Called when you gain addiction points somehow. Takes a mind as argument and sees if you gained the addiction
/datum/addiction/proc/on_gain_addiction_points(datum/mind/victim_mind, new_amount = 0, last_amount = 0)
SHOULD_NOT_OVERRIDE(TRUE)
if(new_amount < addiction_gain_threshold) // Not enough to become addicted
return
if(last_amount >= addiction_gain_threshold) // Already addicted
return
become_addicted(victim_mind)
///Called when you become addicted
/datum/addiction/proc/become_addicted(datum/mind/victim_mind)
LAZYSET(victim_mind.active_addictions, type, 1) //Start at first cycle.
SEND_SIGNAL(victim_mind.current, COMSIG_CARBON_GAIN_ADDICTION, victim_mind)
victim_mind.current.log_message("has become addicted to [name].", LOG_GAME)
///Called when you lose addiction poitns somehow. Takes a mind as argument and sees if you lost the addiction
/datum/addiction/proc/on_lose_addiction_points(datum/mind/victim_mind, new_amount = 0, last_amount = 0)
SHOULD_NOT_OVERRIDE(TRUE)
if(last_amount < addiction_loss_threshold) // Was not addicted last check
return FALSE
if(new_amount >= addiction_loss_threshold) // Is still addicted
return FALSE
lose_addiction(victim_mind)
return TRUE
/datum/addiction/proc/lose_addiction(datum/mind/victim_mind)
victim_mind.current.clear_mood_event("[type]_addiction")
SEND_SIGNAL(victim_mind.current, COMSIG_CARBON_LOSE_ADDICTION, victim_mind)
to_chat(victim_mind.current, span_notice("You feel like you've gotten over your need for drugs."))
end_withdrawal(victim_mind.current)
LAZYREMOVE(victim_mind.active_addictions, type)
/datum/addiction/proc/process_addiction(mob/living/carbon/affected_carbon, seconds_per_tick)
// Acts as if you're on the drug at all times, while also forcibly preventing the effects of withdrawal by returning early.
if(HAS_TRAIT(affected_carbon, TRAIT_NO_WITHDRAWALS))
end_withdrawal(affected_carbon)
return FALSE
var/current_addiction_cycle = LAZYACCESS(affected_carbon.mind.active_addictions, type) //If this is null, we're not addicted
var/on_drug_of_this_addiction = FALSE
for(var/datum/reagent/possible_drug as anything in affected_carbon.reagents.reagent_list) //Go through the drugs in our system
for(var/addiction in possible_drug.addiction_types) //And check all of their addiction types
if(addiction == type && possible_drug.volume >= addiction_relief_treshold) //If one of them matches, and we have enough of it in our system, we're not losing addiction
if(current_addiction_cycle)
end_withdrawal(affected_carbon) //stop the pain
on_drug_of_this_addiction = TRUE
break
var/withdrawal_stage
switch(current_addiction_cycle)
if(WITHDRAWAL_STAGE1_START_CYCLE to WITHDRAWAL_STAGE1_END_CYCLE)
withdrawal_stage = 1
if(WITHDRAWAL_STAGE2_START_CYCLE to WITHDRAWAL_STAGE2_END_CYCLE)
withdrawal_stage = 2
if(WITHDRAWAL_STAGE3_START_CYCLE to INFINITY)
withdrawal_stage = 3
else
withdrawal_stage = 0
if(!on_drug_of_this_addiction && !HAS_TRAIT(affected_carbon, TRAIT_HOPELESSLY_ADDICTED))
if(affected_carbon.mind.remove_addiction_points(type, addiction_loss_per_stage[withdrawal_stage + 1] * seconds_per_tick)) //If true was returned, we lost the addiction!
return
if(!on_drug_of_this_addiction && HAS_TRAIT(affected_carbon, TRAIT_ADDICTIONRESILIENT) && affected_carbon.mind.remove_addiction_points(type, addiction_loss_per_stage[withdrawal_stage + 2] * seconds_per_tick))
return
if(!current_addiction_cycle) //Dont do the effects if were not on drugs
return FALSE
switch(current_addiction_cycle)
if(WITHDRAWAL_STAGE1_START_CYCLE)
withdrawal_enters_stage_1(affected_carbon)
if(WITHDRAWAL_STAGE2_START_CYCLE)
withdrawal_enters_stage_2(affected_carbon)
if(WITHDRAWAL_STAGE3_START_CYCLE)
withdrawal_enters_stage_3(affected_carbon)
///One cycle is 2 seconds
switch(withdrawal_stage)
if(1)
withdrawal_stage_1_process(affected_carbon, seconds_per_tick)
if(2)
withdrawal_stage_2_process(affected_carbon, seconds_per_tick)
if(3)
withdrawal_stage_3_process(affected_carbon, seconds_per_tick)
LAZYADDASSOC(affected_carbon.mind.active_addictions, type, 1 * seconds_per_tick) //Next cycle!
/// Called when addiction enters stage 1
/datum/addiction/proc/withdrawal_enters_stage_1(mob/living/carbon/affected_carbon)
affected_carbon.add_mood_event("[type]_addiction", light_withdrawal_moodlet, name)
/// Called when addiction enters stage 2
/datum/addiction/proc/withdrawal_enters_stage_2(mob/living/carbon/affected_carbon)
affected_carbon.add_mood_event("[type]_addiction", medium_withdrawal_moodlet, name)
/// Called when addiction enters stage 3
/datum/addiction/proc/withdrawal_enters_stage_3(mob/living/carbon/affected_carbon)
affected_carbon.add_mood_event("[type]_addiction", severe_withdrawal_moodlet, name)
/datum/addiction/proc/end_withdrawal(mob/living/carbon/affected_carbon)
LAZYSET(affected_carbon.mind.active_addictions, type, 1) //Keeps withdrawal at first cycle.
affected_carbon.clear_mood_event("[type]_addiction")
/// Called when addiction is in stage 1 every process
/datum/addiction/proc/withdrawal_stage_1_process(mob/living/carbon/affected_carbon, seconds_per_tick)
if(SPT_PROB(5, seconds_per_tick))
to_chat(affected_carbon, span_danger("[withdrawal_stage_messages[1]]"))
/// Called when addiction is in stage 2 every process
/datum/addiction/proc/withdrawal_stage_2_process(mob/living/carbon/affected_carbon, seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick) )
to_chat(affected_carbon, span_danger("[withdrawal_stage_messages[2]]"))
/// Called when addiction is in stage 3 every process
/datum/addiction/proc/withdrawal_stage_3_process(mob/living/carbon/affected_carbon, seconds_per_tick)
if(SPT_PROB(15, seconds_per_tick))
to_chat(affected_carbon, span_danger("[withdrawal_stage_messages[3]]"))