Files
MGOOOOOOandRoxy 82bef2b7cd The Inversenning : Narcotics + Other Reagents (Part 1) (#91430)
## About The Pull Request

Please read the contents of my HackMD to see what my PR does, as well as
further elaboration on the reagents and why it's good for the game
overall.

https://hackmd.io/@MGO/B1YX80nMT

## Contents
Introducing new inverse reagents for existing narcotics and other
reagents! This push includes...

**Naloxone** : New medicine! Requires equal parts Morphine, Hydrogen
Peroxide, Bromine and Ethanol to be made. Opioid antagonist that purges
drowsiness and narcotics from the patient, restores breath loss and
accelerates addiction recovery. Consumption Rate at 0.2u.


![spess1](https://github.com/user-attachments/assets/65dd8e1e-4e52-4263-8d1f-9fb40c416435)

**Permonid** : Inverse of Krokodil. Highly potent sedative that provides
the best painkilling effects, but is also extremely addictive. Speeds up
surgery times by 30%. Consumption Rate at 0.1u.


![spess2](https://github.com/user-attachments/assets/9a07f6db-8ae6-4d0c-bed4-5ca3f96a8d01)

**Monkey Dust** : Inverse of Bath Salts. Oop aak chee aak eek chee. Eek
aak oop chee oop aak aak!! (Consumption Rate at 0.2u.)


https://github.com/user-attachments/assets/cbd5ea48-9c0f-49ca-ba59-59cd65599641

(You can also combine 50u Monkey Powder with 10u Monkey Dust to make an
angry monkey!)

![spess3](https://github.com/user-attachments/assets/f55c4af5-a058-4ec8-9119-7da5352e9c3a)

**Epoetin Alfa** : Inverse of Aranesp. Synthetic medication that induces
blood regeneration, heals liver damage and synthesizes Sanguirite when
the patient is bleeding. Causes several side effects if taken for too
long. Consumption Rate at 0.25u.


![spess5](https://github.com/user-attachments/assets/f7d73a6a-4218-4ca0-a718-76b333f9d3b5)

(Overdose in action.)


https://github.com/user-attachments/assets/27a51a11-0e42-4000-9c96-ba10cbd9e18b

**Sadness** : Inverse of Happiness. Causes severe depressive behavior in
users, and actively purges other antidepressants. Being hugged by a
friendly person that gives good hugs will purge all Sadness unless the
user has the Bad Touch trait. Consumption Rate at 0.1u.


https://github.com/user-attachments/assets/874b0549-1d96-4f4f-ad95-65f780a68436


![spess4](https://github.com/user-attachments/assets/b971f8ef-e318-4129-80bf-d45cfab2cf57)

**Maldium** : Inverse of Baldium. Potent psychotropic that causes
intense anger within users. On end consumption, user will experience a
burst of burn damage that scales with the amount of time the user was
enraged. Consumption Rate at 0.4u.


https://github.com/user-attachments/assets/31a4700e-32b5-4855-a266-45bfde62f718

**Dulling Reagent** : Inverse of Colorful Reagent. Extremely drab
coloring pigment that is favored by corporations who wish to maximize
suffering. Forces Colorblindness trauma in consumers. Consumption Rate
at 0.4u, lowered to 0.04u if overdosing.


https://github.com/user-attachments/assets/3db461d1-26aa-4c77-ad3d-44794230b391

**Newtonium** : Inverse of Gravitum. Experimental reagent that induces
heavy gravokinetic effects on users. Consumption Rate at 1u.


https://github.com/user-attachments/assets/b20e5200-9beb-40a2-8d37-c0d44f0fb4ef

## Why It's Good For The Game

This is an effort to add more variety to the existing inverse reagent
system within chemistry. Not only should this variety serve to provide
additional options for a Chemist to experiment with, they should also
broaden the possibilities for already existing strategies.

## Changelog

:cl:MGO
add: Introduces new inverse reagents for Krokodil, Bath Salts, Aranesp,
Happiness, Baldium, Colorful Reagent and Gravitum!
add: An alternate reaction output has been added for Monkey Powder.
Instead of 1u Water, add 10u Monkey Dust to make an angry monkey!
add: Adds a medicine: Naloxone! Requires equal parts Morphine, Hydrogen
Peroxide, Bromine and Ethanol to be made. Purges opioid-class reagents,
can also help with mitigating drowsiness and breath loss. Also purges
good moodlets associated with opiates and replaces them with negative
moodlets, so don't expect your patient to be happy about losing their
high!
/🆑
2025-06-21 22:21:49 -04:00

140 lines
6.8 KiB
Plaintext

///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"
///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)
var/current_addiction_point_amount = victim_mind.addiction_points[type]
if(current_addiction_point_amount < addiction_gain_threshold) //Not enough to become addicted
return
if(LAZYACCESS(victim_mind.active_addictions, type)) //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)
var/current_addiction_point_amount = victim_mind.addiction_points[type]
if(!LAZYACCESS(victim_mind.active_addictions, type)) //Not addicted
return FALSE
if(current_addiction_point_amount > addiction_loss_threshold) //Not enough to stop being 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, times_fired)
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]]"))