mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-30 23:49:21 +01:00
Reagent Addictions (#17498)
* Addictions * improvements to addiction code * some small revamps * some polishing to reagent code * some more fixes * wiki updated for addiction * proper addiction sync on respawn * final cleanup, config * coffee handle addiction proc * fixed global var * Addictions and Gives alcohol special effects Disables the harder addictions Gives nicotine an a special effect * remove >0 * safety * Update medicine.dm * Update medicine.dm * Update food_drinks.dm * update lazydefines * disable alcohol addiction on virgo * use lazylen, proper addiction end messages * cure message bugfix * use right args * proper macro --------- Co-authored-by: C.L. <killer65311@gmail.com>
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
// Addictions
|
||||
|
||||
// Addictions work using a combined counter var. If a reagent is in the list returned by get_addictive_reagents(), it will be added to the addiction_counters[] assoc list by its id.
|
||||
// If it is present in your body, and you are NOT addicted, it will count DOWNWARD. When it reaches the "addiction proc" you will become addicted. By default you will become addicted at
|
||||
// ADDICTION_PROC negative points. FASTADDICT_PROC and SLOWADDICT_PROC are also used depending on the reagent's addiction speed. This is to prevent booze being as addictive as bliss.
|
||||
// If you are addicted to a chem, and have it present in your body, the counter will quickly climb back up to ADDICTION_PEAK. Refreshing your addiction entirely.
|
||||
|
||||
// Once the addiction proc is reached you will become addicted. The counter will be set to ADDICTION_PEAK and begin counting DOWNWARD. Each addicted reagent has a handle_addiction() proc. The default
|
||||
// implimentation of it will perform various effects once you are under 100 points of addiction. Such as vomiting, organ damage, and other bad effects for not feeding the addiction. Check that
|
||||
// code for exact logic. Inaprovaline is intended to suppress withdrawl effects. Reagents may override the handle_addiction proc to have their own special handling. Like reagents that kill you if you
|
||||
// do not feed their withdrawls. The handle_addiction proc also handles if you become cured of your addiction! If it returns 0, it will end your addiction.
|
||||
|
||||
#define ADDICTION_PROC -4000
|
||||
#define SLOWADDICT_PROC -8000
|
||||
#define FASTADDICT_PROC -1000
|
||||
#define POISONADDICT_PROC -100
|
||||
#define ADDICTION_PEAK 300
|
||||
|
||||
/mob/living/carbon/proc/sync_addictions()
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if(!species)
|
||||
return
|
||||
if(!species.traits)
|
||||
return
|
||||
// Rebuild addictions from traits
|
||||
LAZYCLEARLIST(addictions)
|
||||
LAZYCLEARLIST(addiction_counters)
|
||||
for(var/TR in species.traits)
|
||||
var/datum/trait/T = GLOB.all_traits[TR]
|
||||
if(!T)
|
||||
continue
|
||||
if(!T.addiction)
|
||||
continue
|
||||
addict_to_reagent(T.addiction, TRUE)
|
||||
|
||||
/mob/living/proc/handle_addictions()
|
||||
PROTECTED_PROC(TRUE)
|
||||
// Empty so it can be overridden
|
||||
|
||||
/mob/living/carbon/handle_addictions()
|
||||
// Don't process during vore stuff... It was originally just absorbed, but lets give some mercy to rp focused servers.
|
||||
if(isbelly(loc))
|
||||
return
|
||||
// All addictions start at 0.
|
||||
var/list/addict = list()
|
||||
for(var/datum/reagent/R in bloodstr.reagent_list)
|
||||
var/reagentid = R.id
|
||||
if(istype(SSchemistry.chemical_reagents[reagentid], /datum/reagent/ethanol))
|
||||
reagentid = REAGENT_ID_ETHANOL
|
||||
if(reagentid in get_addictive_reagents(ADDICT_ALL))
|
||||
addict.Add(reagentid)
|
||||
// Only needed for alcohols, will interfere with pills if you detect other things!
|
||||
for(var/datum/reagent/R in ingested.reagent_list)
|
||||
var/reagentid = R.id
|
||||
if(istype(SSchemistry.chemical_reagents[reagentid], /datum/reagent/ethanol))
|
||||
reagentid = REAGENT_ID_ETHANOL
|
||||
if(istype(SSchemistry.chemical_reagents[reagentid], /datum/reagent/drink/coffee))
|
||||
reagentid = REAGENT_ID_COFFEE
|
||||
if(reagentid in get_addictive_reagents(ADDICT_ALL))
|
||||
addict.Add(reagentid)
|
||||
|
||||
for(var/A in addict)
|
||||
if(!LAZYFIND(addictions,A))
|
||||
LAZYADD(addictions,A)
|
||||
LAZYSET(addiction_counters,A,0)
|
||||
|
||||
if(LAZYACCESS(addiction_counters,A) <= 0)
|
||||
// Build addiction until it procs
|
||||
if(LAZYFIND(addiction_counters, A))
|
||||
addiction_counters[A] -= rand(1,3)
|
||||
|
||||
if(LAZYACCESS(addiction_counters,A) < SLOWADDICT_PROC)
|
||||
LAZYSET(addiction_counters,A,SLOWADDICT_PROC)
|
||||
// Check for addition
|
||||
if(A in get_addictive_reagents(ADDICT_SLOW))
|
||||
// Slowest addictions for some medications
|
||||
if(LAZYACCESS(addiction_counters,A) <= SLOWADDICT_PROC)
|
||||
addict_to_reagent(A, FALSE)
|
||||
if(A in get_addictive_reagents(ADDICT_FAST))
|
||||
// quickly addict to these drugs, bliss, oxyco etc
|
||||
if(LAZYACCESS(addiction_counters,A) <= FASTADDICT_PROC)
|
||||
addict_to_reagent(A, FALSE)
|
||||
else
|
||||
// slower addiction over a longer period, cigs and painkillers mostly
|
||||
if(LAZYACCESS(addiction_counters,A) <= ADDICTION_PROC)
|
||||
addict_to_reagent(A, FALSE)
|
||||
else
|
||||
// satiating addiction we already have
|
||||
if(LAZYACCESS(addiction_counters,A) < ADDICTION_PEAK)
|
||||
if(LAZYACCESS(addiction_counters,A) < 100)
|
||||
LAZYSET(addiction_counters,A,100)
|
||||
var/datum/reagent/RR = SSchemistry.chemical_reagents[A]
|
||||
var/message = RR.addiction_refresh_message()
|
||||
if(message)
|
||||
to_chat(src, message)
|
||||
if(LAZYFIND(addiction_counters, A))
|
||||
addiction_counters[A] += rand(8,13)
|
||||
|
||||
// For all counters above 100, count down
|
||||
// For all under 0, count up to 0 randomly, reducing initial addiction buildup if you didn't proc it
|
||||
if(LAZYLEN(addictions))
|
||||
var/C = pick(addictions)
|
||||
// return to normal... we didn't haven't been addicted yet, but we shouldn't become addicted instantly next time if it's been a few hours!
|
||||
if(LAZYACCESS(addiction_counters,C) < 0)
|
||||
if(prob(15) && LAZYFIND(addiction_counters, C))
|
||||
addiction_counters[C] += 1
|
||||
// proc reagent's withdrawl
|
||||
var/datum/reagent/RE = SSchemistry.chemical_reagents[C]
|
||||
var/addict_counter_before = LAZYACCESS(addiction_counters,C)
|
||||
if(LAZYACCESS(addiction_counters,C) > 0)
|
||||
LAZYSET(addiction_counters,C,RE.handle_addiction(src,species.reagent_tag)) // withdrawl can modify the value however it deems fit as you are affected by it
|
||||
// remove if finished
|
||||
if(LAZYACCESS(addiction_counters,C) == 0)
|
||||
var/message = RE.addiction_cure_message()
|
||||
if(addict_counter_before > 0 && message) // Only show cure message if we were addicted to it prior!
|
||||
to_chat(src, message)
|
||||
LAZYREMOVE(addictions,C)
|
||||
LAZYREMOVE(addiction_counters,C)
|
||||
|
||||
/mob/living/carbon/proc/addict_to_reagent(var/reagentid, var/round_start)
|
||||
PRIVATE_PROC(TRUE)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if(isSynthetic()) // Should this be allowed? I guess you can roleplay Bender as an FBP? Trait in the future?
|
||||
return
|
||||
// Check if serverconfig allows addiction during the round. Otherwise only allow spawning with addictions
|
||||
var/allow_addiction = round_start || CONFIG_GET(flag/can_addict_during_round)
|
||||
if(!allow_addiction)
|
||||
return
|
||||
if(!LAZYFIND(addictions,reagentid))
|
||||
LAZYADD(addictions,reagentid)
|
||||
LAZYSET(addiction_counters,reagentid,ADDICTION_PEAK)
|
||||
|
||||
/mob/living/carbon/proc/get_addiction_to_reagent(var/reagentid) // returns counter's value or 0
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
return LAZYACCESS(addiction_counters,reagentid)
|
||||
|
||||
/mob/living/carbon/proc/refresh_all_addictions()
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if(!addiction_counters)
|
||||
return
|
||||
for(var/reagentid in addiction_counters)
|
||||
LAZYSET(addiction_counters,reagentid,ADDICTION_PEAK)
|
||||
|
||||
/mob/living/carbon/proc/clear_all_addictions() // This is probably not a good idea to call as some addictions are intended to be uncurable, like artificial sustenance.
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
LAZYCLEARLIST(addictions)
|
||||
LAZYCLEARLIST(addiction_counters)
|
||||
|
||||
/mob/living/carbon/proc/get_all_addictions()
|
||||
RETURN_TYPE(/list)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
var/list/addict = list()
|
||||
if(addiction_counters)
|
||||
for(var/key in addiction_counters)
|
||||
addict.Add(key)
|
||||
return addict
|
||||
|
||||
#undef ADDICTION_PROC
|
||||
#undef SLOWADDICT_PROC
|
||||
#undef FASTADDICT_PROC
|
||||
#undef POISONADDICT_PROC
|
||||
#undef ADDICTION_PEAK
|
||||
@@ -23,6 +23,9 @@
|
||||
|
||||
var/does_not_breathe = 0 //Used for specific mobs that can't take advantage of the species flags (changelings)
|
||||
|
||||
VAR_PROTECTED/list/addictions = null // contains currently addicted chem reagent IDs
|
||||
VAR_PROTECTED/list/addiction_counters = null // contains counters by reagent ID
|
||||
|
||||
//these two help govern taste. The first is the last time a taste message was shown to the plaer.
|
||||
//the second is the message in question.
|
||||
var/last_taste_time = 0
|
||||
|
||||
@@ -759,3 +759,59 @@
|
||||
cost = 0
|
||||
category = 0
|
||||
custom_only = FALSE
|
||||
|
||||
|
||||
// Addictions
|
||||
/datum/trait/neutral/addiction_alcohol
|
||||
name = "Addiction - Alcohol"
|
||||
desc = "You have become chemically dependant to any alcoholic drink, and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_ETHANOL
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
/datum/trait/neutral/addiction_bliss
|
||||
name = "Addiction - " + REAGENT_BLISS
|
||||
desc = "You have become chemically dependant to " + REAGENT_BLISS + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_BLISS
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
/datum/trait/neutral/addiction_coffee
|
||||
name = "Addiction - " + REAGENT_COFFEE
|
||||
desc = "You have become chemically dependant to " + REAGENT_COFFEE + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_COFFEE
|
||||
custom_only = FALSE
|
||||
|
||||
/datum/trait/neutral/addiction_hyper
|
||||
name = "Addiction - " + REAGENT_HYPERZINE
|
||||
desc = "You have become chemically dependant to " + REAGENT_HYPERZINE + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_HYPERZINE
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
/datum/trait/neutral/addiction_nicotine
|
||||
name = "Addiction - " + REAGENT_NICOTINE
|
||||
desc = "You have become chemically dependant to " + REAGENT_NICOTINE + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_NICOTINE
|
||||
custom_only = FALSE
|
||||
|
||||
/datum/trait/neutral/addiction_oxy
|
||||
name = "Addiction - " + REAGENT_OXYCODONE
|
||||
desc = "You have become chemically dependant to " + REAGENT_OXYCODONE + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_OXYCODONE
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
/datum/trait/neutral/addiction_painkiller
|
||||
name = "Addiction - Pain Killers"
|
||||
desc = "You have become chemically dependant to " + REAGENT_TRAMADOL + ", and need to regularly consume it or suffer withdrawals."
|
||||
addiction = REAGENT_ID_TRAMADOL
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
/datum/trait/neutral/addiction_asustenance
|
||||
name = "Unstable Vat Grown Body"
|
||||
desc = "You are chemically dependant to " + REAGENT_ASUSTENANCE + ", and need to regularly consume it or your body decays."
|
||||
addiction = REAGENT_ID_ASUSTENANCE
|
||||
custom_only = FALSE
|
||||
hidden = TRUE //Disabled on Virgo
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
var/mutation = 0 // Mutation to give (or 0)
|
||||
var/disability = 0 // Disability to give (or 0)
|
||||
var/sdisability = 0 // SDisability to give (or 0)
|
||||
var/addiction = null // Addiction reagent, null otherwise
|
||||
var/activation_message = null // If not null, shows a message when activated as a gene
|
||||
var/deactivation_message = null // If not null, shows a message when deactivated as a gene
|
||||
var/list/primitive_expression_messages=list() // Monkey's custom emote when they have this gene!
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc.
|
||||
handle_disabilities() // eye, ear, brain damages
|
||||
handle_addictions() // Dwugs
|
||||
handle_statuses() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
|
||||
|
||||
update_canmove()
|
||||
|
||||
@@ -425,6 +425,7 @@
|
||||
new_character.dna.b_type = client.prefs.b_type
|
||||
new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed
|
||||
new_character.sync_organ_dna()
|
||||
new_character.sync_addictions() // Handle round-start addictions
|
||||
new_character.initialize_vessel()
|
||||
|
||||
for(var/lang in client.prefs.alternate_languages)
|
||||
|
||||
Reference in New Issue
Block a user