mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
[MIRROR] Reagent Addictions (#10888)
Co-authored-by: Will <7099514+Willburd@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
committed by
GitHub
parent
ca7345cb67
commit
dc9ccc60c2
@@ -1,11 +1,11 @@
|
||||
// Helper macros to aid in optimizing lazy instantiation of lists.
|
||||
// All of these are null-safe, you can use them without knowing if the list var is initialized yet
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
///Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
|
||||
|
||||
// Ensures L is initailized after this point
|
||||
#define LAZYINITLIST(L) if (!L) L = list()
|
||||
#define LAZYINITLIST(L) if (!L) { L = list(); }
|
||||
|
||||
// Sets a L back to null iff it is empty
|
||||
#define UNSETEMPTY(L) if (L && !length(L)) L = null
|
||||
@@ -21,7 +21,7 @@
|
||||
// Adds I to L, initalizing L if necessary, if I is not already in L
|
||||
#define LAZYDISTINCTADD(L, I) if(!L) { L = list(); } L |= I;
|
||||
|
||||
#define LAZYFIND(L, V) L ? L.Find(V) : 0
|
||||
#define LAZYFIND(L, V) (L ? L.Find(V) : 0)
|
||||
|
||||
// Reads I from L safely - Works with both associative and traditional lists.
|
||||
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null)
|
||||
@@ -38,6 +38,9 @@
|
||||
#define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; }
|
||||
#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null
|
||||
|
||||
// Sets a list to null
|
||||
#define LAZYNULL(L) L = null
|
||||
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) { L.Cut(); L = null; }
|
||||
|
||||
|
||||
@@ -266,6 +266,8 @@
|
||||
#define REAGENT_ID_MENTHOL "menthol"
|
||||
#define REAGENT_EARTHSBLOOD "Earthsblood"
|
||||
#define REAGENT_ID_EARTHSBLOOD "earthsblood"
|
||||
#define REAGENT_ASUSTENANCE "Artificial Sustenance"
|
||||
#define REAGENT_ID_ASUSTENANCE "a_sustenance"
|
||||
|
||||
|
||||
// Virology
|
||||
|
||||
25
code/__defines/addictions.dm
Normal file
25
code/__defines/addictions.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
#define CE_WITHDRAWL "withdrawl" // Withdrawl symptoms
|
||||
|
||||
#define ADDICT_NORMAL 1
|
||||
#define ADDICT_SLOW 2
|
||||
#define ADDICT_FAST 3
|
||||
#define ADDICT_POISON 4
|
||||
#define ADDICT_ALL 5
|
||||
|
||||
GLOBAL_LIST_INIT(reagent_addictive_standard,list(REAGENT_ID_AMBROSIAEXTRACT,REAGENT_ID_TALUMQUEM,REAGENT_ID_METHYLPHENIDATE))
|
||||
GLOBAL_LIST_INIT(reagent_addictive_slow,list(REAGENT_ID_TRAMADOL,REAGENT_ID_OXYCODONE,REAGENT_ID_TRICORDRAZINE,REAGENT_ID_ASUSTENANCE,REAGENT_ID_ETHANOL,REAGENT_ID_NICOTINE,REAGENT_ID_COFFEE))
|
||||
GLOBAL_LIST_INIT(reagent_addictive_fast,list(REAGENT_ID_HYPERZINE,REAGENT_ID_BLISS))
|
||||
GLOBAL_LIST_INIT(reagent_addictive_poison,list())
|
||||
|
||||
/proc/get_addictive_reagents(var/addict_type)
|
||||
RETURN_TYPE(/list)
|
||||
switch(addict_type)
|
||||
if(ADDICT_NORMAL)
|
||||
return GLOB.reagent_addictive_standard // Most reagents go here
|
||||
if(ADDICT_SLOW)
|
||||
return GLOB.reagent_addictive_slow // Booze, Cigs
|
||||
if(ADDICT_FAST)
|
||||
return GLOB.reagent_addictive_fast // Bliss, hyperzine, hardcore drugs
|
||||
if(ADDICT_POISON)
|
||||
return GLOB.reagent_addictive_poison // Poisons that use handle_addiction() for unique longterm poisoning
|
||||
return GLOB.reagent_addictive_standard + GLOB.reagent_addictive_fast + GLOB.reagent_addictive_slow + GLOB.reagent_addictive_poison
|
||||
@@ -13,6 +13,9 @@
|
||||
integer = FALSE
|
||||
default = 1.0
|
||||
|
||||
/datum/config_entry/flag/can_addict_during_round
|
||||
default = FALSE
|
||||
|
||||
// FIXME: Unused
|
||||
///datum/config_entry/flag/revival_pod_plants
|
||||
// default = TRUE
|
||||
|
||||
@@ -1092,10 +1092,10 @@ SUBSYSTEM_DEF(internal_wiki)
|
||||
SSinternal_wiki.add_icon(data, initial(beaker_path.icon), initial(beaker_path.icon_state), R.color)
|
||||
// Get internal data
|
||||
data["description"] = R.description
|
||||
/* Downstream features
|
||||
data["addictive"] = 0
|
||||
if(R.id in addictives)
|
||||
data["addictive"] = (R.id in fast_addictives) ? 2 : 1
|
||||
if(R.id in get_addictive_reagents(ADDICT_ALL))
|
||||
data["addictive"] = TRUE
|
||||
/* Downstream features
|
||||
data["industrial_use"] = R.industrial_use
|
||||
data["supply_points"] = R.supply_conversion_value ? R.supply_conversion_value : 0
|
||||
var/value = R.supply_conversion_value * REAGENTS_PER_SHEET * SSsupply.points_per_money
|
||||
@@ -1111,9 +1111,9 @@ SUBSYSTEM_DEF(internal_wiki)
|
||||
/datum/internal_wiki/page/chemical/get_print()
|
||||
var/body = ""
|
||||
body += "<b>Description: </b>[data["description"]]<br>"
|
||||
/* Downstream features
|
||||
if(data["addictive"])
|
||||
body += "<b>DANGER, [data["addictive"] > 1 ? "highly " : ""]addictive.</b><br>"
|
||||
body += "<b>DANGER, addictive.</b><br>"
|
||||
/* Downstream features
|
||||
if(data["industrial_use"])
|
||||
body += "<b>Industrial Use: </b>[data["industrial_use"]]<br>"
|
||||
var/tank_size = CARGOTANKER_VOLUME
|
||||
|
||||
@@ -308,6 +308,29 @@
|
||||
dat += span_warning("Anatomical irregularities detected in subject.")
|
||||
dat += "<br>"
|
||||
//CHOMPedit end
|
||||
// Addictions
|
||||
if(H.get_addiction_to_reagent(REAGENT_ID_ASUSTENANCE) > 0)
|
||||
dat += span_warning("Biologically unstable, requires [REAGENT_ASUSTENANCE] to function properly.")
|
||||
dat += "<br>"
|
||||
for(var/addic in H.get_all_addictions())
|
||||
if(H.get_addiction_to_reagent(addic) > 0 && (advscan >= 2 || H.get_addiction_to_reagent(addic) <= 120)) // high enough scanner upgrade detects addiction even if not almost withdrawling
|
||||
var/datum/reagent/R = SSchemistry.chemical_reagents[addic]
|
||||
if(R.id == REAGENT_ID_ASUSTENANCE)
|
||||
continue
|
||||
if(advscan >= 1)
|
||||
// Shows multiple
|
||||
if(advscan >= 2 && H.get_addiction_to_reagent(addic) <= 80)
|
||||
dat += span_warning("Experiencing withdrawls from [R.name], [REAGENT_INAPROVALINE] treatment recomended.")
|
||||
dat += "<br>"
|
||||
else
|
||||
dat += span_warning("Chemical dependance detected: [R.name].")
|
||||
dat += "<br>"
|
||||
else
|
||||
// Shows single
|
||||
dat += span_warning("Chemical dependance detected.")
|
||||
dat += "<br>"
|
||||
break
|
||||
// Appendix
|
||||
for(var/obj/item/organ/internal/appendix/a in H.internal_organs)
|
||||
var/severity = ""
|
||||
if(a.inflamed > 3)
|
||||
|
||||
@@ -244,6 +244,7 @@
|
||||
M.client.prefs.copy_to(new_character)
|
||||
new_character.dna.ResetUIFrom(new_character)
|
||||
new_character.sync_organ_dna()
|
||||
new_character.sync_addictions()
|
||||
new_character.key = M.key
|
||||
new_character.mind.loaded_from_ckey = picked_ckey
|
||||
new_character.mind.loaded_from_slot = picked_slot
|
||||
|
||||
@@ -315,6 +315,7 @@
|
||||
prob(2);/obj/item/selectable_item/chemistrykit/size,
|
||||
prob(2);/obj/item/selectable_item/chemistrykit/gender,
|
||||
prob(2);/obj/item/clothing/gloves/bluespace/emagged,
|
||||
prob(2);/obj/item/reagent_containers/glass/beaker/vial/sustenance,
|
||||
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
|
||||
prob(1);/obj/item/nif/bad,
|
||||
prob(1);/obj/item/radio_jammer,
|
||||
|
||||
@@ -525,6 +525,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
new_character.dna.ResetUIFrom(new_character)
|
||||
new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed
|
||||
new_character.sync_organ_dna()
|
||||
new_character.sync_addictions() // These are addicitions our profile wants... May as well give them!
|
||||
new_character.initialize_vessel()
|
||||
if(inhabit)
|
||||
new_character.key = player_key
|
||||
|
||||
162
code/modules/mob/living/carbon/addictions.dm
Normal file
162
code/modules/mob/living/carbon/addictions.dm
Normal file
@@ -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
|
||||
@@ -24,6 +24,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
|
||||
|
||||
@@ -761,3 +761,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()
|
||||
|
||||
@@ -434,6 +434,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)
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
else if(is_broken())
|
||||
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
|
||||
|
||||
// General organ damage from withdraw, kidneys do a lot of the work
|
||||
if(prob(70) && owner.chem_effects[CE_WITHDRAWL])
|
||||
take_damage(owner.chem_effects[CE_WITHDRAWL] * 0.05 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_WITHDRAWL] * 0.3 * PROCESS_ACCURACY)
|
||||
|
||||
/obj/item/organ/internal/kidneys/handle_organ_proc_special()
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -43,6 +43,15 @@
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY)
|
||||
|
||||
// General organ damage from withdraw
|
||||
if(prob(20) && owner.chem_effects[CE_WITHDRAWL])
|
||||
take_damage(owner.chem_effects[CE_WITHDRAWL] * 0.05 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
|
||||
if(filter_effect < 2) //Withdrawls intensified
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_WITHDRAWL] * 0.2 * PROCESS_ACCURACY)
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_WITHDRAWL] * 0.1 * PROCESS_ACCURACY)
|
||||
|
||||
|
||||
/obj/item/organ/internal/liver/handle_germ_effects()
|
||||
. = ..() //Up should return an infection level as an integer
|
||||
if(!.) return
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
if(src.damage < 0)
|
||||
src.damage = 0
|
||||
|
||||
// General organ damage from withdraw
|
||||
if(prob(20) && owner.chem_effects[CE_WITHDRAWL])
|
||||
take_damage(owner.chem_effects[CE_WITHDRAWL] * 0.05 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_WITHDRAWL] * 0.2 * PROCESS_ACCURACY)
|
||||
|
||||
/obj/item/organ/internal/spleen/handle_germ_effects()
|
||||
. = ..() //Up should return an infection level as an integer
|
||||
if(!.) return
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
SSinternal_wiki.add_icon(subdata, initial(beaker_path.icon), initial(beaker_path.icon_state), R.color)
|
||||
// Get internal data
|
||||
subdata["description"] = R.description
|
||||
subdata["addictive"] = 0
|
||||
if(R.id in get_addictive_reagents(ADDICT_ALL))
|
||||
subdata["addictive"] = TRUE
|
||||
subdata["flavor"] = R.taste_description
|
||||
subdata["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type)
|
||||
subdata["beakerAmount"] = found_reagents[ID]
|
||||
|
||||
@@ -1248,3 +1248,10 @@
|
||||
result = REAGENT_ID_PROTEIN
|
||||
required_reagents = list(REAGENT_ID_ENZYME = 1, REAGENT_ID_SPIDERTOXIN = 1, REAGENT_ID_SIFSAP = 1)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/artificial_sustenance
|
||||
name = REAGENT_ASUSTENANCE
|
||||
id = REAGENT_ID_ASUSTENANCE
|
||||
result = REAGENT_ID_ASUSTENANCE
|
||||
required_reagents = list(REAGENT_ID_NUTRIMENT = 1, REAGENT_ID_MUTAGEN = 1, REAGENT_ID_PHORON = 1)
|
||||
result_amount = 1
|
||||
|
||||
@@ -431,3 +431,7 @@
|
||||
matter = list(MAT_WOOD = 50)
|
||||
drop_sound = 'sound/items/drop/wooden.ogg'
|
||||
pickup_sound = 'sound/items/pickup/wooden.ogg'
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/vial/sustenance
|
||||
name = "vial (artificial sustenance)"
|
||||
prefill = list(REAGENT_ID_ASUSTENANCE = 30)
|
||||
|
||||
@@ -214,6 +214,75 @@
|
||||
to_chat(usr, span_notice("The solution dissolves the ink on the book."))
|
||||
return
|
||||
|
||||
/datum/reagent/ethanol/handle_addiction(var/mob/living/carbon/M, var/alien)
|
||||
// A copy of the base with withdrawl, but with much less effects, such as vomiting.
|
||||
var/current_addiction = M.get_addiction_to_reagent(id)
|
||||
var/realistic_addiction = FALSE //DEFAULT set to FALSE. Toggle to TRUE for a more realistic addiction with potentially fatal side effects.
|
||||
// slow degrade
|
||||
if(prob(8))
|
||||
current_addiction -= 1
|
||||
// withdrawl mechanics
|
||||
if(!(CE_STABLE in M.chem_effects)) //Without stabilization effects
|
||||
if(current_addiction <= 60)
|
||||
M.pulse = PULSE_2FAST
|
||||
if(prob(2))
|
||||
if(current_addiction < 90 && prob(10))
|
||||
to_chat(M, span_warning("[pick("You feel miserable.","You feel nauseous.","You get a raging headache.")]"))
|
||||
M.adjustHalLoss(7)
|
||||
M.make_jittery(25) //Restlessness.
|
||||
else if(current_addiction <= 20)
|
||||
to_chat(M, span_danger("You feel absolutely awful. You need some some liquor. Now."))
|
||||
if(realistic_addiction && prob(20)) //1 in 5 on a 1 in 50, so 1 in 250 chance. DTs
|
||||
to_chat(src, span_red("You have a seizure!"))
|
||||
for(var/mob/O in viewers(M, null))
|
||||
if(O == src)
|
||||
continue
|
||||
O.show_message(span_danger("[M] starts having a seizure!"), 1)
|
||||
M.Paralyse(10)
|
||||
M.make_jittery(1000)
|
||||
else if(current_addiction <= 50)
|
||||
to_chat(M, span_warning("You're really craving some alcohol. You feel nauseated."))
|
||||
if(realistic_addiction)
|
||||
M.emote("vomit")
|
||||
M.AdjustConfused(10) // Disorientation.
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("You're feeling the need for some booze."))
|
||||
// effects
|
||||
if(current_addiction < 60 && prob(20)) // 1 in 50 x 1 in 5 = 1 in 250
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
M.drop_item() //Hand tremors
|
||||
if(realistic_addiction)
|
||||
M.add_chemical_effect(CE_WITHDRAWL, rand(4,10) * REM)
|
||||
else //Stabilization effects
|
||||
if(current_addiction <= 60)
|
||||
M.pulse = PULSE_FAST
|
||||
if(prob(2))
|
||||
if(current_addiction < 90 && prob(10))
|
||||
to_chat(M, span_warning("[pick("You feel a light throbbing in your head.","Your stomach feels upset.","Your .")]"))
|
||||
M.adjustHalLoss(3)
|
||||
M.make_jittery(10) //Restlessness.
|
||||
else if(current_addiction <= 20)
|
||||
to_chat(M, span_warning("You feel nauseated."))
|
||||
if(realistic_addiction)
|
||||
M.emote("vomit")
|
||||
M.AdjustConfused(10) // Disorientation.
|
||||
else if(current_addiction <= 50)
|
||||
to_chat(M, span_warning("Your head throbs and the room spins."))
|
||||
if(realistic_addiction)
|
||||
M.AdjustConfused(3) // Disorientation.
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("A drink would be nice."))
|
||||
// effects
|
||||
if(current_addiction < 60 && prob(5)) // 1 in 50 x 1 in 20 = 1 in 1000
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
M.drop_item() //Hand tremors
|
||||
if(current_addiction <= 0) //safety
|
||||
current_addiction = 0
|
||||
return current_addiction
|
||||
|
||||
/datum/reagent/ethanol/addiction_cure_message()
|
||||
return span_notice("You feel your symptoms end, you no longer feel the craving for alcohol.")
|
||||
|
||||
/datum/reagent/fluorine
|
||||
name = REAGENT_FLUORINE
|
||||
id = REAGENT_ID_FLUORINE
|
||||
|
||||
@@ -210,6 +210,37 @@
|
||||
color = "#181818"
|
||||
high_messages = FALSE
|
||||
|
||||
/datum/reagent/drugs/nicotine/handle_addiction(var/mob/living/carbon/M, var/alien)
|
||||
// A copy of the base with withdrawl, but with much less effects, such as vomiting.
|
||||
var/current_addiction = M.get_addiction_to_reagent(id)
|
||||
// slow degrade
|
||||
if(prob(8))
|
||||
current_addiction -= 1
|
||||
// withdrawl mechanics
|
||||
if(prob(2))
|
||||
if(!(CE_STABLE in M.chem_effects)) //Without stabilization effects
|
||||
if(current_addiction < 90 && prob(10))
|
||||
to_chat(M, span_warning("[pick("You feel miserable.","You feel nauseous.","You get a raging headache.")]"))
|
||||
M.adjustHalLoss(5)
|
||||
else if(current_addiction <= 20)
|
||||
to_chat(M, span_danger("You feel absolutely awful. You need some [name]. Now."))
|
||||
if(prob(10)) //1 in 10 on top of a 1 in 50, so thats a 1 in 500 chance. Seems low enough to not be disruptive.
|
||||
M.emote("vomit")
|
||||
else if(current_addiction <= 50)
|
||||
to_chat(M, span_warning("You're really craving some [name]."))
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("You're feeling the need for some [name]."))
|
||||
// effects
|
||||
if(current_addiction < 60 && prob(20))
|
||||
M.emote(pick("pale","shiver","twitch", "cough"))
|
||||
else
|
||||
if(current_addiction < 90 && prob(10))
|
||||
to_chat(M, span_warning("[pick("You feel a slight craving for some [name].","Your stomach feels slightly upset.","You feel a slight pain in your head.")]"))
|
||||
if(current_addiction <= 0) //safety
|
||||
current_addiction = 0
|
||||
return current_addiction
|
||||
|
||||
|
||||
/*///////////////////////////////////////////////////////////////////////////
|
||||
/// PSYCHIATRIC DRUGS /////
|
||||
/// /////
|
||||
|
||||
@@ -1634,6 +1634,28 @@
|
||||
//M.apply_effect(3, STUTTER) //VOREStation Edit end
|
||||
M.make_jittery(5)
|
||||
|
||||
/datum/reagent/drink/coffee/handle_addiction(var/mob/living/carbon/M, var/alien)
|
||||
// A copy of the base with withdrawl, but with much less effects, no vomiting and sometimes halloss
|
||||
var/current_addiction = M.get_addiction_to_reagent(id)
|
||||
// slow degrade
|
||||
if(prob(8))
|
||||
current_addiction -= 1
|
||||
// withdrawl mechanics
|
||||
if(prob(2))
|
||||
if(current_addiction < 90 && prob(10))
|
||||
to_chat(M, span_warning("[pick("You feel miserable.","You feel sluggish.","You get a small headache.")]"))
|
||||
M.adjustHalLoss(2)
|
||||
else if(current_addiction <= 50)
|
||||
to_chat(M, span_warning("You're really craving some [name]."))
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("You're feeling the need for some [name]."))
|
||||
// effects
|
||||
if(current_addiction < 60 && prob(20))
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(current_addiction <= 0) //safety
|
||||
current_addiction = 0
|
||||
return current_addiction
|
||||
|
||||
/datum/reagent/drink/coffee/icecoffee
|
||||
name = REAGENT_ICECOFFEE
|
||||
id = REAGENT_ID_ICECOFFEE
|
||||
|
||||
@@ -1425,3 +1425,64 @@
|
||||
M.druggy = max(M.druggy, 20)
|
||||
M.hallucination = max(M.hallucination, 3)
|
||||
M.adjustBrainLoss(1 * removed) //your life for your mind. The Earthmother's Tithe.
|
||||
|
||||
|
||||
// Vat clone stablizer
|
||||
/datum/reagent/acid/artificial_sustenance
|
||||
name = REAGENT_ASUSTENANCE
|
||||
id = REAGENT_ID_ASUSTENANCE
|
||||
description = "A drug used to stablize vat grown bodies. Often used to control the lifespan of biological experiments." // Who else remembers Cybersix?
|
||||
taste_description = "burning metal"
|
||||
reagent_state = LIQUID
|
||||
color = "#31d422"
|
||||
overdose = 15
|
||||
overdose_mod = 1.2
|
||||
scannable = 1
|
||||
|
||||
/datum/reagent/acid/artificial_sustenance/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
// You need me...
|
||||
if(M.get_addiction_to_reagent(REAGENT_ID_ASUSTENANCE))
|
||||
return
|
||||
// Continue to acid damage, no changes on injection or splashing, as this is meant to be edible only to those pre-addicted to it! Not a snowflake acid that doesn't hurt you!
|
||||
. = ..()
|
||||
|
||||
/datum/reagent/acid/artificial_sustenance/handle_addiction(var/mob/living/carbon/M, var/alien)
|
||||
// A copy of the base with withdrawl, but with death, and different messages
|
||||
var/current_addiction = M.get_addiction_to_reagent(id)
|
||||
// slow degrade
|
||||
if(prob(2))
|
||||
current_addiction -= 1
|
||||
// withdrawl mechanics
|
||||
if(prob(2))
|
||||
if(current_addiction <= 40)
|
||||
to_chat(M, span_danger("You're dying for some [name]!"))
|
||||
else if(current_addiction <= 60)
|
||||
to_chat(M, span_warning("You're really craving some [name]."))
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("You're feeling the need for some [name]."))
|
||||
// effects
|
||||
if(current_addiction < 60 && prob(20))
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
// Agony and death!
|
||||
if(current_addiction <= 20)
|
||||
if(prob(12))
|
||||
M.adjustToxLoss( rand(1,4) )
|
||||
M.adjustBruteLoss( rand(1,4) )
|
||||
M.adjustOxyLoss( rand(1,4) )
|
||||
// proc side effect
|
||||
if(current_addiction <= 30)
|
||||
if(prob(3))
|
||||
M.Weaken(2)
|
||||
M.emote("vomit")
|
||||
M.add_chemical_effect(CE_WITHDRAWL, rand(9,14) * REM)
|
||||
else if(current_addiction <= 40)
|
||||
if(prob(3))
|
||||
M.emote("vomit")
|
||||
M.add_chemical_effect(CE_WITHDRAWL, rand(5,9) * REM)
|
||||
else if(current_addiction <= 50)
|
||||
if(prob(2))
|
||||
M.emote("vomit")
|
||||
// Sustenance requirements cannot be escaped!
|
||||
if(current_addiction <= 0)
|
||||
current_addiction = 40
|
||||
return current_addiction
|
||||
|
||||
64
code/modules/reagents/reagents/withdrawl.dm
Normal file
64
code/modules/reagents/reagents/withdrawl.dm
Normal file
@@ -0,0 +1,64 @@
|
||||
/datum/reagent/proc/handle_addiction(var/mob/living/carbon/M, var/alien)
|
||||
// overridable proc for custom withdrawl behaviors, standard is chills, cravings, vomiting, weakness and CE_WITHDRAWL organ damage
|
||||
if(alien == IS_DIONA)
|
||||
return 0
|
||||
var/current_addiction = M.get_addiction_to_reagent(id)
|
||||
// slow degrade
|
||||
if(prob(8))
|
||||
current_addiction -= 1
|
||||
// withdrawl mechanics
|
||||
if(current_addiction < 10)
|
||||
if(prob(2))
|
||||
M.Weaken(1)
|
||||
else if(current_addiction > 10)
|
||||
if(CE_STABLE in M.chem_effects) // Inaprovaline can be used to treat addiction
|
||||
if(prob(1))
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
to_chat(M, span_notice("You feel sluggish."))
|
||||
if(2)
|
||||
to_chat(M, span_notice("You feel awful."))
|
||||
if(3)
|
||||
to_chat(M, span_notice("Everything feels sore."))
|
||||
// effects
|
||||
if(current_addiction < 100 && prob(10))
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(current_addiction <= 60)
|
||||
if(prob(1))
|
||||
M.Weaken(2)
|
||||
if(prob(5) && prob(1))
|
||||
M.emote("vomit")
|
||||
else
|
||||
// send a message to notify players
|
||||
if(prob(2))
|
||||
if(current_addiction <= 40)
|
||||
to_chat(M, span_danger("You're dying for some [name]!"))
|
||||
else if(current_addiction <= 60)
|
||||
to_chat(M, span_warning("You're really craving some [name]."))
|
||||
else if(current_addiction <= 100)
|
||||
to_chat(M, span_notice("You're feeling the need for some [name]."))
|
||||
// effects
|
||||
if(current_addiction < 100 && prob(20))
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
// proc side effect
|
||||
if(current_addiction <= 30)
|
||||
if(prob(3))
|
||||
M.Weaken(2)
|
||||
M.emote("vomit")
|
||||
M.add_chemical_effect(CE_WITHDRAWL, rand(2,4) * REM)
|
||||
else if(current_addiction <= 50)
|
||||
if(prob(3))
|
||||
M.emote("vomit")
|
||||
M.add_chemical_effect(CE_WITHDRAWL, rand(1,3) * REM)
|
||||
else if(current_addiction <= 70)
|
||||
if(prob(2))
|
||||
M.emote("vomit")
|
||||
if(current_addiction <= 0) //safety
|
||||
current_addiction = 0
|
||||
return current_addiction
|
||||
|
||||
/datum/reagent/proc/addiction_cure_message()
|
||||
return span_notice("You feel your symptoms end, you no longer feel the craving for [name].")
|
||||
|
||||
/datum/reagent/proc/addiction_refresh_message()
|
||||
return span_notice("You feel rejuvenated as the [name] rushes through you.")
|
||||
@@ -157,6 +157,7 @@
|
||||
new_character.dna.ResetUIFrom(new_character)
|
||||
new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed
|
||||
new_character.sync_organ_dna()
|
||||
new_character.sync_addictions() // These are addicitions our profile wants... May as well give them!
|
||||
new_character.initialize_vessel()
|
||||
if(ghost.mind)
|
||||
ghost.mind.transfer_to(new_character)
|
||||
|
||||
@@ -146,6 +146,7 @@ Please do not abuse this ability.
|
||||
new_character.dna.ResetUIFrom(new_character)
|
||||
new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed
|
||||
new_character.sync_organ_dna()
|
||||
new_character.sync_addictions()
|
||||
new_character.initialize_vessel()
|
||||
new_character.key = player_key
|
||||
if(new_character.mind)
|
||||
|
||||
@@ -69,6 +69,9 @@ FOOTSTEP_VOLUME 45
|
||||
## Whether or not humans show an area message when they die.
|
||||
SHOW_HUMAN_DEATH_MESSAGE
|
||||
|
||||
## If chemicals and drinks can give addictions during a round. Otherwise they are only accessible through traits or exotic effects.
|
||||
#CAN_ADDICT_DURING_ROUND
|
||||
|
||||
## Alert level descriptions
|
||||
ALERT_DESC_GREEN All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced.
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "code\__defines\_reagents_ch.dm"
|
||||
#include "code\__defines\_tick.dm"
|
||||
#include "code\__defines\action.dm"
|
||||
#include "code\__defines\addictions.dm"
|
||||
#include "code\__defines\admin.dm"
|
||||
#include "code\__defines\admin_ch.dm"
|
||||
#include "code\__defines\admin_verb.dm"
|
||||
@@ -3250,6 +3251,7 @@
|
||||
#include "code\modules\mob\living\bot\mulebot_vr.dm"
|
||||
#include "code\modules\mob\living\bot\secbot.dm"
|
||||
#include "code\modules\mob\living\bot\SLed209bot.dm"
|
||||
#include "code\modules\mob\living\carbon\addictions.dm"
|
||||
#include "code\modules\mob\living\carbon\breathe.dm"
|
||||
#include "code\modules\mob\living\carbon\carbon.dm"
|
||||
#include "code\modules\mob\living\carbon\carbon_defense.dm"
|
||||
@@ -4328,6 +4330,7 @@
|
||||
#include "code\modules\reagents\reagents\virology.dm"
|
||||
#include "code\modules\reagents\reagents\vore_ch.dm"
|
||||
#include "code\modules\reagents\reagents\vore_vr.dm"
|
||||
#include "code\modules\reagents\reagents\withdrawl.dm"
|
||||
#include "code\modules\recycling\conveyor2.dm"
|
||||
#include "code\modules\recycling\disposal-construction.dm"
|
||||
#include "code\modules\recycling\disposal.dm"
|
||||
|
||||
Reference in New Issue
Block a user