Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into job-menu-improvements

This commit is contained in:
Poojawa
2019-08-10 23:26:20 -05:00
145 changed files with 8822 additions and 1448 deletions
+2 -1
View File
@@ -24,7 +24,7 @@
// start global signals with "!", this used to be necessary but now it's just a formatting choice
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
//////////////////////////////////////////////////////////////////
// /datum signals
@@ -159,6 +159,7 @@
#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag)
#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
// /obj/item signals
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
+1
View File
@@ -16,6 +16,7 @@
#define INVESTIGATE_EXONET "exonet"
#define INVESTIGATE_NANITES "nanites"
#define INVESTIGATE_CIRCUIT "circuit"
#define INVESTIGATE_FERMICHEM "fermichem"
#define INVESTIGATE_RCD "rcd"
// Logging types for log_message()
+3 -4
View File
@@ -57,7 +57,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define BODYPARTS_LAYER 28 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
#define MARKING_LAYER 27 //Matrixed body markings because clashing with snouts?
#define BODY_ADJ_LAYER 26 //certain mutantrace features (snout, body markings) that must appear above the body parts
#define GENITALS_ADJ_LAYER 25
#define GENITALS_FRONT_LAYER 25 //Draws some genitalia above clothes and the TAUR body if need be.
#define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup)
#define FRONT_MUTATIONS_LAYER 23 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
#define DAMAGE_LAYER 22 //damage indicators (cuts and burns)
@@ -69,7 +69,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define EARS_LAYER 17
#define BODY_TAUR_LAYER 16
#define SUIT_LAYER 15
#define GENITALS_FRONT_LAYER 14 //Draws some genitalia above clothes and the TAUR body if need be.
#define GLASSES_LAYER 13
#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 11
@@ -83,7 +82,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define HANDS_LAYER 3
#define BODY_FRONT_LAYER 2
#define FIRE_LAYER 1 //If you're on fire
#define TOTAL_LAYERS 31 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
#define TOTAL_LAYERS 30 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
@@ -496,4 +495,4 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define PREF_SAVELOAD_COOLDOWN 5
#define VOMIT_TOXIC 1
#define VOMIT_PURPLE 2
#define VOMIT_PURPLE 2
+3 -1
View File
@@ -28,4 +28,6 @@
#define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER"
#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER"
#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
+7 -1
View File
@@ -2,7 +2,13 @@
#define LIQUID 2
#define GAS 3
// reagents_flags defines
//reagents reaction var defines
#define REAGENT_NORMAL_PH 7.000
#define REAGENT_PH_ACCURACY 0.001
#define REAGENT_PURITY_ACCURACY 0.001
#define DEFAULT_SPECIFIC_HEAT 200
// container_type defines
#define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes.
#define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes.
+2
View File
@@ -44,6 +44,8 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
#define STATUS_EFFECT_GEISTRACKER /datum/status_effect/geis_tracker //if you're using geis, this tracks that and keeps you from using scripture
+1 -1
View File
@@ -31,4 +31,4 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
#define WORLDTIMEOFDAY2TEXT(format) GAMETIMESTAMP(format, world.timeofday)
#define TIME_STAMP(format, showds) showds ? "[WORLDTIMEOFDAY2TEXT(format)]:[world.timeofday % 10]" : WORLDTIMEOFDAY2TEXT(format)
#define STATION_TIME(display_only) ((((world.time - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0)
#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format)
#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format)
+5
View File
@@ -108,6 +108,8 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
#define TRAIT_FEARLESS "fearless"
#define TRAIT_UNSTABLE "unstable"
#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
@@ -144,12 +146,15 @@
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
#define TRAIT_NYMPHO "nymphomania"
#define TRAIT_MASO "masochism"
#define TRAIT_HIGH_BLOOD "high_blood"
#define TRAIT_PHARMA "hepatic_pharmacokinesis"
#define TRAIT_PARA "paraplegic"
#define TRAIT_EMPATH "empath"
#define TRAIT_FRIENDLY "friendly"
#define TRAIT_ASSBLASTUSA "assblastusa"
#define TRAIT_CULT_EYES "cult_eyes"
// common trait sources
#define TRAIT_GENERIC "generic"
#define EYE_DAMAGE "eye_damage"
+1
View File
@@ -58,6 +58,7 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
//Genitals and Arousal Lists
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
GLOBAL_LIST_EMPTY(gentlemans_organ_names)
GLOBAL_LIST_EMPTY(balls_shapes_list)
GLOBAL_LIST_EMPTY(balls_shapes_icons)
GLOBAL_LIST_EMPTY(breasts_size_list)
+2 -1
View File
@@ -52,7 +52,8 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "baloney pony", "schlanger")
for(var/K in GLOB.breasts_shapes_list)
var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
GLOB.breasts_shapes_icons[K] = value.icon_state
@@ -110,6 +110,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 1,
/obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint
/obj/item/storage/pill_bottle/penis_enlargement = 2,
/obj/item/storage/pill_bottle/breast_enlargement = 2,
/obj/item/clothing/shoes/wheelys = 1,
/obj/item/clothing/shoes/kindleKicks = 1,
/obj/item/autosurgeon/penis = 1,
@@ -0,0 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(chemistry)
wait = 5
flags = SS_KEEP_TIMING
+72
View File
@@ -0,0 +1,72 @@
/datum/brain_trauma/hypnosis
name = "Hypnosis"
desc = "Patient's unconscious is completely enthralled by a word or sentence, focusing their thoughts and actions on it."
scan_desc = "looping thought pattern"
gain_text = ""
lose_text = ""
resilience = TRAUMA_RESILIENCE_SURGERY
var/hypnotic_phrase = ""
var/regex/target_phrase
/datum/brain_trauma/hypnosis/New(phrase, quirk = FALSE)
if(!phrase)
qdel(src)
if(quirk == TRUE)
hypnotic_phrase = phrase
else
friendliify(phrase)
if(IsAdminAdvancedProcCall())
to_chat(usr, "<span class='danger'>Hypnosis New() skipped due to try/catch incompatibility with admin proccalling.</span>")
qdel(src)
try
target_phrase = new("(\\b[hypnotic_phrase]\\b)","ig")
catch(var/exception/e)
stack_trace("[e] on [e.file]:[e.line]")
qdel(src)
..()
/datum/brain_trauma/hypnosis/proc/friendliify(phrase)
phrase = replacetext(lowertext(phrase), "kill", "hug")
phrase = replacetext(lowertext(phrase), "murder", "cuddle")
phrase = replacetext(lowertext(phrase), "harm", "snuggle")
phrase = replacetext(lowertext(phrase), "decapitate", "headpat")
phrase = replacetext(lowertext(phrase), "strangle", "meow at")
phrase = replacetext(lowertext(phrase), "suicide", "self-love")
phrase = replacetext(lowertext(phrase), "lynch", "kiss")
hypnotic_phrase = phrase
/datum/brain_trauma/hypnosis/on_gain()
message_admins("[ADMIN_LOOKUPFLW(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.")
log_game("[key_name(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.")
to_chat(owner, "<span class='reallybig hypnophrase'>[hypnotic_phrase]</span>")
to_chat(owner, "<span class='notice'>[pick("You feel your thoughts focusing on this phrase... you can't seem to get it out of your head.",\
"Your head hurts, but this is all you can think of. It must be vitally important.",\
"You feel a part of your mind repeating this over and over. You need to follow these words.",\
"Something about this sounds... right, for some reason. You feel like you should follow these words.",\
"These words keep echoing in your mind. You find yourself completely fascinated by them.")]</span>")
if(!HAS_TRAIT(owner, "hypnotherapy"))
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You must follow these words. If it isn't a clear order, you can freely interpret how to do so,\
as long as you act like the words are your highest priority.</span>")
else
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You feel an incredible desire to follow these words, but are able to resist it somewhat. If it isn't a clear order, you can freely interpret how to do so,\
however this does not take precedence over your other objectives.</span>")
..()
/datum/brain_trauma/hypnosis/on_lose()
message_admins("[ADMIN_LOOKUPFLW(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
log_game("[key_name(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
to_chat(owner, "<span class='userdanger'>You suddenly snap out of your fixation. The phrase '[hypnotic_phrase]' no longer feels important to you.</span>")
..()
/datum/brain_trauma/hypnosis/on_life()
..()
if(prob(2))
switch(rand(1,2))
if(1)
to_chat(owner, "<i>...[lowertext(hypnotic_phrase)]...</i>")
if(2)
new /datum/hallucination/chat(owner, TRUE, FALSE, "<span class='hypnophrase'>[hypnotic_phrase]</span>")
/datum/brain_trauma/hypnosis/on_hear(message, speaker, message_language, raw_message, radio_freq)
message = target_phrase.Replace(message, "<span class='hypnophrase'>$1</span>")
return message
+6
View File
@@ -31,6 +31,8 @@
/datum/brain_trauma/mild/phobia/on_life()
..()
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return
if(is_blind(owner))
return
if(world.time > next_check && world.time > next_scare)
@@ -70,6 +72,8 @@
/datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq)
if(!owner.can_hear() || world.time < next_scare) //words can't trigger you if you can't hear them *taps head*
return message
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return message
for(var/word in trigger_words)
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
@@ -79,6 +83,8 @@
return message
/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args)
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return
for(var/word in trigger_words)
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
+17
View File
@@ -254,3 +254,20 @@
/datum/brain_trauma/severe/pacifism/on_lose()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT)
..()
//ported from TG
/datum/brain_trauma/severe/hypnotic_stupor
name = "Hypnotic Stupor"
desc = "Patient is prone to episodes of extreme stupor that leaves them extremely suggestible."
scan_desc = "oneiric feedback loop"
gain_text = "<span class='warning'>You feel somewhat dazed.</span>"
lose_text = "<span class='notice'>You feel like a fog was lifted from your mind.</span>"
/datum/brain_trauma/severe/hypnotic_stupor/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway
..()
owner.remove_status_effect(/datum/status_effect/trance)
/datum/brain_trauma/severe/hypnotic_stupor/on_life()
..()
if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance))
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
+60 -1
View File
@@ -6,6 +6,7 @@
var/sanity = 100 //Current sanity
var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy.
var/mood_level = 5 //To track what stage of moodies they're on
var/sanity_level = 5 //To track what stage of sanity they're on
var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets
var/datum/mood_event/list/mood_events = list()
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
@@ -118,6 +119,8 @@
if(owner.client && owner.hud_used)
if(sanity < 25)
screen_obj.icon_state = "mood_insane"
else if (owner.has_status_effect(/datum/status_effect/chem/enthrall))//Fermichem enthral chem, maybe change?
screen_obj.icon_state = "mood_entrance"
else
screen_obj.icon_state = "mood[mood_level]"
@@ -163,6 +166,58 @@
HandleNutrition(owner)
/datum/component/mood/proc/setSanity(amount, minimum=SANITY_INSANE, maximum=SANITY_NEUTRAL)//I'm sure bunging this in here will have no negative repercussions.
var/mob/living/master = parent
if(amount == sanity)
return
// If we're out of the acceptable minimum-maximum range move back towards it in steps of 0.5
// If the new amount would move towards the acceptable range faster then use it instead
if(sanity < minimum && amount < sanity + 0.5)
amount = sanity + 0.5
else if(sanity > maximum && amount > sanity - 0.5)
amount = sanity - 0.5
// Disturbed stops you from getting any more sane
if(HAS_TRAIT(master, TRAIT_UNSTABLE))
sanity = min(amount,sanity)
else
sanity = amount
switch(sanity)
if(SANITY_INSANE to SANITY_CRAZY)
setInsanityEffect(MAJOR_INSANITY_PEN)
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1.5) //Did we change something ? movetypes is runtiming, movetypes=(~FLYING))
sanity_level = 6
if(SANITY_CRAZY to SANITY_UNSTABLE)
setInsanityEffect(MINOR_INSANITY_PEN)
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1)//, movetypes=(~FLYING))
sanity_level = 5
if(SANITY_UNSTABLE to SANITY_DISTURBED)
setInsanityEffect(0)
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5)//, movetypes=(~FLYING))
sanity_level = 4
if(SANITY_DISTURBED to SANITY_NEUTRAL)
setInsanityEffect(0)
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
sanity_level = 3
if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences
setInsanityEffect(0)
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
sanity_level = 2
if(SANITY_GREAT+1 to INFINITY)
setInsanityEffect(0)
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
sanity_level = 1
//update_mood_icon()
/datum/component/mood/proc/setInsanityEffect(newval)//More code so that the previous proc works
if(newval == insanity_effect)
return
var/mob/living/master = parent
master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
insanity_effect = newval
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
IncreaseSanity(0.5)
@@ -175,6 +230,10 @@
insanity_effect = (MINOR_INSANITY_PEN)
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
// Disturbed stops you from getting any more sane - I'm just gonna bung this in here
var/mob/living/owner = parent
if(HAS_TRAIT(owner, TRAIT_UNSTABLE))
return
if(sanity > maximum)
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
else
@@ -195,7 +254,7 @@
if(the_event.timeout)
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
return 0 //Don't have to update the event.
the_event = new type(src, param)
the_event = new type(src, param)//This causes a runtime for some reason, was this me? No - there's an event floating around missing a definition.
mood_events[category] = the_event
update_mood()
@@ -44,7 +44,7 @@ Bonus
if(4, 5)
M.adjustOxyLoss(-7, 0)
M.losebreath = max(0, M.losebreath - 4)
if(regenerate_blood && M.blood_volume < BLOOD_VOLUME_NORMAL)
if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio))
M.blood_volume += 1
else
if(prob(base_message_chance))
+1 -1
View File
@@ -96,4 +96,4 @@
/datum/looping_sound/proc/on_stop()
if(end_sound)
play(end_sound)
play(end_sound)
+5 -5
View File
@@ -6,24 +6,24 @@
/datum/mood_event/quality_nice
description = "<span class='nicegreen'>That drink wasn't bad at all.</span>\n"
mood_change = 1
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/quality_good
description = "<span class='nicegreen'>That drink was pretty good.</span>\n"
mood_change = 2
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/quality_verygood
description = "<span class='nicegreen'>That drink was great!</span>\n"
mood_change = 3
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/quality_fantastic
description = "<span class='nicegreen'>That drink was amazing!</span>\n"
mood_change = 4
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/amazingtaste
description = "<span class='nicegreen'>Amazing taste!</span>\n"
mood_change = 50
mood_change = 50 //Is this not really high..?
timeout = 10 MINUTES
+16
View File
@@ -37,3 +37,19 @@
/datum/mood_event/withdrawal_critical/add_effects(drug_name)
description = "<span class='boldwarning'>[drug_name]! [drug_name]! [drug_name]!</span>\n"
/datum/mood_event/happiness_drug
description = "<span class='nicegreen'>I can't feel anything and I never want this to end.</span>\n"
mood_change = 10
/datum/mood_event/happiness_drug_good_od
description = "<span class='nicegreen'>YES! YES!! YES!!!</span>\n"
mood_change = 20
timeout = 300
//special_screen_obj = "mood_happiness_good" Originally in tg, but I personally think they look dumb
/datum/mood_event/happiness_drug_bad_od
description = "<span class='boldwarning'>NO! NO!! NO!!!</span>\n"
mood_change = -20
timeout = 300
//special_screen_obj = "mood_happiness_bad" Originally in tg
@@ -1,3 +1,5 @@
/datum/mood_event/handcuffed
description = "<span class='warning'>I guess my antics have finally caught up with me.</span>\n"
mood_change = -1
@@ -17,7 +19,7 @@
/datum/mood_event/burnt_thumb
description = "<span class='warning'>I shouldn't play with lighters...</span>\n"
mood_change = -1
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/cold
description = "<span class='warning'>It's way too cold in here.</span>\n"
@@ -30,17 +32,17 @@
/datum/mood_event/creampie
description = "<span class='warning'>I've been creamed. Tastes like pie flavor.</span>\n"
mood_change = -2
timeout = 1800
timeout = 3 MINUTES
/datum/mood_event/slipped
description = "<span class='warning'>I slipped. I should be more careful next time...</span>\n"
mood_change = -2
timeout = 1800
timeout = 3 MINUTES
/datum/mood_event/eye_stab
description = "<span class='boldwarning'>I used to be an adventurer like you, until I took a screwdriver to the eye.</span>\n"
mood_change = -4
timeout = 1800
timeout = 3 MINUTES
/datum/mood_event/delam //SM delamination
description = "<span class='boldwarning'>Those God damn engineers can't do anything right...</span>\n"
@@ -50,12 +52,12 @@
/datum/mood_event/depression
description = "<span class='warning'>I feel sad for no particular reason.</span>\n"
mood_change = -9
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/shameful_suicide //suicide_acts that return SHAME, like sord
description = "<span class='boldwarning'>I can't even end it all!</span>\n"
mood_change = -10
timeout = 600
timeout = 1 MINUTES
/datum/mood_event/dismembered
description = "<span class='boldwarning'>AHH! I WAS USING THAT LIMB!</span>\n"
@@ -69,7 +71,7 @@
/datum/mood_event/tased
description = "<span class='warning'>There's no \"z\" in \"taser\". It's in the zap.</span>\n"
mood_change = -3
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/embedded
description = "<span class='boldwarning'>Pull it out!</span>\n"
@@ -78,7 +80,7 @@
/datum/mood_event/table
description = "<span class='warning'>Someone threw me on a table!</span>\n"
mood_change = -2
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/table/add_effects()
if(ishuman(owner))
@@ -117,6 +119,30 @@
description = "<span class='warning'>I'm missing my family heirloom...</span>\n"
mood_change = -4
/datum/mood_event/healsbadman
description = "<span class='warning'>I feel a lot better, but wow that was disgusting.</span>\n"
mood_change = -4
timeout = 2 MINUTES
/datum/mood_event/jittery
description = "<span class='warning'>I'm nervous and on edge and I can't stand still!!</span>\n"
mood_change = -2
/datum/mood_event/vomit
description = "<span class='warning'>I just threw up. Gross.</span>\n"
mood_change = -2
timeout = 2 MINUTES
/datum/mood_event/vomitself
description = "<span class='warning'>I just threw up all over myself. This is disgusting.</span>\n"
mood_change = -4
timeout = 3 MINUTES
/datum/mood_event/painful_medicine
description = "<span class='warning'>Medicine may be good for me but right now it stings like hell.</span>\n"
mood_change = -5
timeout = 1 MINUTES
/datum/mood_event/loud_gong
description = "<span class='warning'>That loud gong noise really hurt my ears!</span>\n"
mood_change = -3
@@ -1,7 +1,7 @@
/datum/mood_event/hug
description = "<span class='nicegreen'>Hugs are nice.</span>\n"
mood_change = 1
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/arcade
description = "<span class='nicegreen'>I beat the arcade game!</span>\n"
@@ -50,7 +50,7 @@
/datum/mood_event/jolly
description = "<span class='nicegreen'>I feel happy for no particular reason.</span>\n"
mood_change = 6
timeout = 1200
timeout = 2 MINUTES
/datum/mood_event/focused
description = "<span class='nicegreen'>I have a goal, and I will reach it, whatever it takes!</span>\n" //Used for syndies, nukeops etc so they can focus on their goals
@@ -76,6 +76,20 @@
mood_change = 3
timeout = 600
/datum/mood_event/chemical_euphoria
description = "<span class='nicegreen'>Heh...hehehe...hehe...</span>\n"
mood_change = 4
/datum/mood_event/chemical_laughter
description = "<span class='nicegreen'>Laughter really is the best medicine! Or is it?</span>\n"
mood_change = 4
timeout = 3 MINUTES
/datum/mood_event/chemical_superlaughter
description = "<span class='nicegreen'>*WHEEZE*</span>\n"
mood_change = 12
timeout = 3 MINUTES
/datum/mood_event/betterhug
description = "<span class='nicegreen'>Someone was very nice to me.</span>\n"
mood_change = 3
@@ -94,8 +108,8 @@
/datum/mood_event/happy_empath
description = "<span class='warning'>Someone seems happy!</span>\n"
mood_change = 2
mood_change = 3
timeout = 600
/datum/mood_event/happy_empath/add_effects(var/mob/happytarget)
description = "<span class='warning'>[happytarget.name]'s happiness is infectious!</span>\n"
description = "<span class='nicegreen'>[happytarget.name]'s happiness is infectious!</span>\n"
+1 -1
View File
@@ -59,4 +59,4 @@
/datum/mood_event/nice_shower
description = "<span class='nicegreen'>I have recently had a nice shower.</span>\n"
mood_change = 2
timeout = 1800
timeout = 3 MINUTES
+98
View File
@@ -507,3 +507,101 @@
desc = "Your body is covered in blue ichor! You can't be revived by vitality matrices."
icon_state = "ichorial_stain"
alerttooltipstyle = "clockcult"
datum/status_effect/pacify
id = "pacify"
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
duration = 100
alert_type = null
/datum/status_effect/pacify/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
duration = set_duration
. = ..()
/datum/status_effect/pacify/on_apply()
ADD_TRAIT(owner, TRAIT_PACIFISM, "status_effect")
return ..()
/datum/status_effect/pacify/on_remove()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "status_effect")
/datum/status_effect/trance
id = "trance"
status_type = STATUS_EFFECT_UNIQUE
duration = 300
tick_interval = 10
examine_text = "<span class='warning'>SUBJECTPRONOUN seems slow and unfocused.</span>"
var/stun = TRUE
var/triggered = FALSE
alert_type = null
/obj/screen/alert/status_effect/trance
name = "Trance"
desc = "Everything feels so distant, and you can feel your thoughts forming loops inside your head..."
icon_state = "high"
/datum/status_effect/trance/tick()
if(HAS_TRAIT(owner, "hypnotherapy"))
if(triggered == TRUE)
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/hypnotize)
ADD_TRAIT(owner, TRAIT_MUTE, "trance")
if(!owner.has_quirk(/datum/quirk/monochromatic))
owner.add_client_colour(/datum/client_colour/monochrome)
to_chat(owner, "<span class='warning'>[pick("You feel your thoughts slow down...", "You suddenly feel extremely dizzy...", "You feel like you're in the middle of a dream...","You feel incredibly relaxed...")]</span>")
triggered = FALSE
else
return
if(stun)
owner.Stun(60, TRUE, TRUE)
owner.dizziness = 20
/datum/status_effect/trance/on_apply()
if(!iscarbon(owner))
return FALSE
if(HAS_TRAIT(owner, "hypnotherapy"))
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/listen)
return TRUE
alert_type = /obj/screen/alert/status_effect/trance
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/hypnotize)
ADD_TRAIT(owner, TRAIT_MUTE, "trance")
if(!owner.has_quirk(/datum/quirk/monochromatic))
owner.add_client_colour(/datum/client_colour/monochrome)
owner.visible_message("[stun ? "<span class='warning'>[owner] stands still as [owner.p_their()] eyes seem to focus on a distant point.</span>" : ""]", \
"<span class='warning'>[pick("You feel your thoughts slow down...", "You suddenly feel extremely dizzy...", "You feel like you're in the middle of a dream...","You feel incredibly relaxed...")]</span>")
return TRUE
/datum/status_effect/trance/on_creation(mob/living/new_owner, _duration, _stun = TRUE, source_quirk = FALSE)//hypnoquirk makes no visible message, prevents self antag messages, and places phrase below objectives.
duration = _duration
stun = _stun
if(source_quirk == FALSE && HAS_TRAIT(owner, "hypnotherapy"))
REMOVE_TRAIT(owner, "hypnotherapy", ROUNDSTART_TRAIT)
return ..()
/datum/status_effect/trance/on_remove()
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
REMOVE_TRAIT(owner, TRAIT_MUTE, "trance")
owner.dizziness = 0
if(!owner.has_quirk(/datum/quirk/monochromatic))
owner.remove_client_colour(/datum/client_colour/monochrome)
to_chat(owner, "<span class='warning'>You snap out of your trance!</span>")
/datum/status_effect/trance/proc/listen(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
to_chat(owner, "<span class='notice'><i>[speaker] accidentally sets off your implanted trigger, sending you into a hypnotic daze!</i></span>")
triggered = TRUE
/datum/status_effect/trance/proc/hypnotize(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
if(!owner.can_hear())
return
if(speaker == owner)
return
var/mob/living/carbon/C = owner
C.cure_trauma_type(/datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY) //clear previous hypnosis
if(HAS_TRAIT(C, "hypnotherapy"))
addtimer(CALLBACK(C, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, raw_message, TRUE), 10)
else
addtimer(CALLBACK(C, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, raw_message), 10)
addtimer(CALLBACK(C, /mob/living.proc/Stun, 60, TRUE, TRUE), 15) //Take some time to think about it
qdel(src)
+17
View File
@@ -186,3 +186,20 @@
var/obj/item/autosurgeon/gloweyes/gloweyes = new(get_turf(H))
H.equip_to_slot(gloweyes, SLOT_IN_BACKPACK)
H.regenerate_icons()
/datum/quirk/bloodpressure
name = "Polycythemia vera"
desc = "You've a treated form of Polycythemia vera that increases the total blood volume inside of you as well as the rate of replenishment!"
value = 2 //I honeslty dunno if this is a good trait? I just means you use more of medbays blood and make janitors madder, but you also regen blood a lil faster.
mob_trait = TRAIT_HIGH_BLOOD
gain_text = "<span class='notice'>You feel full of blood!</span>"
lose_text = "<span class='notice'>You feel like your blood pressure went down.</span>"
/datum/quirk/bloodpressure/add()
var/mob/living/M = quirk_holder
M.blood_ratio = 1.2
M.blood_volume += 150
/datum/quirk/bloodpressure/remove()
var/mob/living/M = quirk_holder
M.blood_ratio = 1
+9
View File
@@ -354,3 +354,12 @@
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused your voice to be heard.</span>")
qdel(src)
/datum/quirk/unstable
name = "Unstable"
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
value = -2
mob_trait = TRAIT_UNSTABLE
gain_text = "<span class='danger'>There's a lot on your mind right now.</span>"
lose_text = "<span class='notice'>Your mind finally feels calm.</span>"
medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events."
+2 -2
View File
@@ -145,7 +145,7 @@
return
// If the human is losing too much blood, beep.
if(attached.blood_volume < BLOOD_VOLUME_SAFE && prob(5))
if(attached.blood_volume < ( (BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) ) )
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
attached.transfer_blood_to(beaker, amount)
@@ -218,4 +218,4 @@
to_chat(user, "<span class='notice'>[attached ? attached : "No one"] is attached.</span>")
#undef IV_TAKING
#undef IV_INJECTING
#undef IV_INJECTING
+1 -1
View File
@@ -17,7 +17,7 @@
target = get_turf(src)
if(acid_amt)
acid_level = min(acid_amt*acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor.
acid_level = min( (CLAMP(round(acid_amt, 1), 0, INFINITY)) *acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor.
//handle APCs and newscasters and stuff nicely
pixel_x = target.pixel_x + rand(-4,4)
+47 -5
View File
@@ -163,7 +163,37 @@ SLIME SCANNER
msg += "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>\n"
else if (M.getBrainLoss() >= 45)
msg += "\t<span class='alert'>Brain damage detected.</span>\n"
if(iscarbon(M))
if(ishuman(M) && advanced) // Should I make this not advanced?
var/mob/living/carbon/human/H = M
var/obj/item/organ/liver/L = H.getorganslot("liver")
if(L)
if(L.swelling > 20)
msg += "\t<span class='danger'>Subject is suffering from an enlarged liver.</span>\n" //i.e. shrink their liver or give them a transplant.
else
msg += "\t<span class='danger'>Subject's liver is missing.</span>\n"
var/obj/item/organ/tongue/T = H.getorganslot("tongue")
if(T)
if(T.damage > 40)
msg += "\t<span class='danger'>Subject is suffering from severe burn tissue on their tongue.</span>\n" //i.e. their tongue is shot
if(T.name == "fluffy tongue")
msg += "\t<span class='danger'>Subject is suffering from a fluffified tongue. Suggested cure: Yamerol or a tongue transplant.</span>\n"
else
msg += "\t<span class='danger'>Subject's tongue is missing.</span>\n"
var/obj/item/organ/lungs/Lung = H.getorganslot("lungs")
if(Lung)
if(Lung.damage > 150)
msg += "\t<span class='danger'>Subject is suffering from acute emphysema leading to trouble breathing.</span>\n" //i.e. Their lungs are shot
else
msg += "\t<span class='danger'>Subject's lungs have collapsed from trauma!</span>\n"
var/obj/item/organ/genital/penis/P = H.getorganslot("penis")
if(P)
if(P.length>20)
msg += "\t<span class='info'>Subject has a sizeable gentleman's organ at [P.length] inches.</span>\n"
var/obj/item/organ/genital/breasts/Br = H.getorganslot("breasts")
if(Br)
if(Br.cached_size>5)
msg += "\t<span class='info'>Subject has a sizeable bosom with a [Br.size] cup.</span>\n"
var/mob/living/carbon/C = M
if(LAZYLEN(C.get_traumas()))
var/list/trauma_text = list()
@@ -183,7 +213,7 @@ SLIME SCANNER
msg += "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>\n"
if(advanced)
msg += "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>\n"
if (M.radiation)
if(M.radiation)
msg += "\t<span class='alert'>Subject is irradiated.</span>\n"
if(advanced)
msg += "\t<span class='info'>Radiation Level: [M.radiation]%.</span>\n"
@@ -191,6 +221,17 @@ SLIME SCANNER
if(advanced && M.hallucinating())
msg += "\t<span class='info'>Subject is hallucinating.</span>\n"
//MKUltra
if(advanced && M.has_status_effect(/datum/status_effect/chem/enthrall))
msg += "\t<span class='info'>Subject has abnormal brain fuctions.</span>\n"
//Astrogen shenanigans
if(advanced && M.reagents.has_reagent("astral"))
if(M.mind)
msg += "\t<span class='danger'>Warning: subject may be possesed.</span>\n"
else
msg += "\t<span class='notice'>Subject appears to be astrally projecting.</span>\n"
//Eyes and ears
if(advanced)
if(iscarbon(M))
@@ -256,6 +297,7 @@ SLIME SCANNER
for(var/obj/item/bodypart/org in damaged)
msg += "\t\t<span class='info'>[capitalize(org.name)]: [(org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : "<font color='red'>0</font>"]-[(org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : "<font color='#FF8000'>0</font>"]\n"
// Species and body temperature
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -310,7 +352,7 @@ SLIME SCANNER
var/mob/living/carbon/human/H = C
if(H.bleed_rate)
msg += "<span class='danger'>Subject is bleeding!</span>\n"
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_percent = round((C.blood_volume / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
if(blood_id != "blood")//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
@@ -318,9 +360,9 @@ SLIME SCANNER
blood_type = R.name
else
blood_type = blood_id
if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY)
if(C.blood_volume <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.blood_volume > (BLOOD_VOLUME_OKAY*C.blood_ratio))
msg += "<span class='danger'>LOW blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>\n"
else if(C.blood_volume <= BLOOD_VOLUME_OKAY)
else if(C.blood_volume <= (BLOOD_VOLUME_OKAY*C.blood_ratio))
msg += "<span class='danger'>CRITICAL blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>\n"
else
msg += "<span class='info'>Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]</span>\n"
+391 -365
View File
@@ -1,365 +1,391 @@
/* First aid storage
* Contains:
* First Aid Kits
* Pill Bottles
* Dice Pack (in a pill bottle)
*/
/*
* First Aid Kits
*/
/obj/item/storage/firstaid
name = "first-aid kit"
desc = "It's an emergency medical kit for those serious boo-boos."
icon_state = "firstaid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 3
throw_range = 7
var/empty = FALSE
/obj/item/storage/firstaid/regular
icon_state = "firstaid"
desc = "A first aid kit with the ability to heal common types of injuries."
/obj/item/storage/firstaid/regular/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins giving [user.p_them()]self aids with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/storage/firstaid/regular/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/ancient
icon_state = "firstaid"
desc = "A first aid kit with the ability to heal common types of injuries."
/obj/item/storage/firstaid/ancient/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
/obj/item/storage/firstaid/fire
name = "burn treatment kit"
desc = "A specialized medical kit for when the toxins lab <i>-spontaneously-</i> burns down."
icon_state = "ointment"
item_state = "firstaid-ointment"
/obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!</span>")
return FIRELOSS
/obj/item/storage/firstaid/fire/Initialize(mapload)
. = ..()
icon_state = pick("ointment","firefirstaid")
/obj/item/storage/firstaid/fire/PopulateContents()
if(empty)
return
for(var/i in 1 to 3)
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
new /obj/item/reagent_containers/pill/oxandrolone(src)
new /obj/item/reagent_containers/pill/oxandrolone(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/toxin
name = "toxin treatment kit"
desc = "Used to treat toxic blood content and radiation poisoning."
icon_state = "antitoxin"
item_state = "firstaid-toxin"
/obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return TOXLOSS
/obj/item/storage/firstaid/toxin/Initialize(mapload)
. = ..()
icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
/obj/item/storage/firstaid/toxin/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/syringe/charcoal(src)
for(var/i in 1 to 2)
new /obj/item/storage/pill_bottle/charcoal(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/radbgone
name = "radiation treatment kit"
desc = "Used to treat minor toxic blood content and major radiation poisoning."
icon_state = "antitoxin"
item_state = "firstaid-toxin"
/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return TOXLOSS
/obj/item/storage/firstaid/radbgone/PopulateContents()
if(empty)
return
if(prob(50))
new /obj/item/reagent_containers/pill/mutarad(src)
if(prob(80))
new /obj/item/reagent_containers/pill/antirad_plus(src)
new /obj/item/reagent_containers/syringe/charcoal(src)
new /obj/item/storage/pill_bottle/charcoal(src)
new /obj/item/reagent_containers/pill/mutadone(src)
new /obj/item/reagent_containers/pill/antirad(src)
new /obj/item/reagent_containers/food/drinks/bottle/vodka(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/o2
name = "oxygen deprivation treatment kit"
desc = "A box full of oxygen goodies."
icon_state = "o2"
item_state = "firstaid-o2"
/obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/storage/firstaid/o2/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/pill/salbutamol(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/brute
name = "brute trauma treatment kit"
desc = "A first aid kit for when you get toolboxed."
icon_state = "brute"
item_state = "firstaid-brute"
/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/storage/firstaid/brute/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/pill/patch/styptic(src)
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/gauze(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/tactical
name = "combat medical kit"
desc = "I hope you've got insurance."
icon_state = "bezerk"
/obj/item/storage/firstaid/tactical/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/firstaid/tactical/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/defibrillator/compact/combat/loaded(src)
new /obj/item/reagent_containers/hypospray/combat(src)
new /obj/item/reagent_containers/pill/patch/styptic(src)
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
new /obj/item/reagent_containers/syringe/lethal/choral(src)
new /obj/item/clothing/glasses/hud/health/night(src)
/*
* Pill Bottles
*/
/obj/item/storage/pill_bottle
name = "pill bottle"
desc = "It's an airtight container for storing medication."
icon_state = "pill_canister"
icon = 'icons/obj/chemical.dmi'
item_state = "contsolid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
/obj/item/storage/pill_bottle/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.allow_quick_gather = TRUE
STR.click_gather = TRUE
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
/obj/item/storage/pill_bottle/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (TOXLOSS)
/obj/item/storage/pill_bottle/charcoal
name = "bottle of charcoal pills"
desc = "Contains pills used to counter toxins."
/obj/item/storage/pill_bottle/charcoal/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/charcoal(src)
/obj/item/storage/pill_bottle/antirad
name = "bottle of charcoal pills"
desc = "Contains pills used to counter radiation poisoning."
/obj/item/storage/pill_bottle/anitrad/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/antirad(src)
/obj/item/storage/pill_bottle/epinephrine
name = "bottle of epinephrine pills"
desc = "Contains pills used to stabilize patients."
/obj/item/storage/pill_bottle/epinephrine/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/epinephrine(src)
/obj/item/storage/pill_bottle/mutadone
name = "bottle of mutadone pills"
desc = "Contains pills used to treat genetic abnormalities."
/obj/item/storage/pill_bottle/mutadone/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mutadone(src)
/obj/item/storage/pill_bottle/mannitol
name = "bottle of mannitol pills"
desc = "Contains pills used to treat brain damage."
/obj/item/storage/pill_bottle/mannitol/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mannitol(src)
/obj/item/storage/pill_bottle/stimulant
name = "bottle of stimulant pills"
desc = "Guaranteed to give you that extra burst of energy during a long shift!"
/obj/item/storage/pill_bottle/stimulant/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/stimulant(src)
/obj/item/storage/pill_bottle/mining
name = "bottle of patches"
desc = "Contains patches used to treat brute and burn damage."
/obj/item/storage/pill_bottle/mining/PopulateContents()
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/pill/patch/styptic(src)
/obj/item/storage/pill_bottle/zoom
name = "suspicious pill bottle"
desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds."
/obj/item/storage/pill_bottle/zoom/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/zoom(src)
/obj/item/storage/pill_bottle/happy
name = "suspicious pill bottle"
desc = "There is a smiley on the top."
/obj/item/storage/pill_bottle/happy/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/happy(src)
/obj/item/storage/pill_bottle/lsd
name = "suspicious pill bottle"
desc = "There is a badly drawn thing with the shape of a mushroom."
/obj/item/storage/pill_bottle/lsd/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/lsd(src)
/obj/item/storage/pill_bottle/aranesp
name = "suspicious pill bottle"
desc = "The label says 'gotta go fast'."
/obj/item/storage/pill_bottle/aranesp/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/aranesp(src)
/obj/item/storage/pill_bottle/antirad_plus
name = "anti radiation deluxe pill bottle"
desc = "The label says 'Med-Co branded pills'."
/obj/item/storage/pill_bottle/antirad_plus/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/antirad_plus(src)
/obj/item/storage/pill_bottle/mutarad
name = "radiation treatment deluxe pill bottle"
desc = "The label says 'Med-Co branded pills' and below that 'Contains Mutadone in each pill!`."
/obj/item/storage/pill_bottle/mutarad/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mutarad(src)
/obj/item/storage/pill_bottle/penis_enlargement
name = "penis enlargement pills"
desc = "You want penis enlargement pills?"
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/penis_enlargement(src)
/////////////
//Organ Box//
/////////////
/obj/item/storage/belt/organbox
name = "Organ Storge"
desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying"
w_class = WEIGHT_CLASS_BULKY
icon = 'icons/obj/mysterybox.dmi'
icon_state = "organbox_open"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 1
throw_range = 1
/obj/item/storage/belt/organbox/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 16
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
STR.can_hold = typecacheof(list(
/obj/item/storage/pill_bottle,
/obj/item/reagent_containers/hypospray,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/syringe,
/obj/item/clothing/glasses/hud/health,
/obj/item/hemostat,
/obj/item/scalpel,
/obj/item/retractor,
/obj/item/cautery,
/obj/item/surgical_drapes,
/obj/item/autosurgeon,
/obj/item/organ,
/obj/item/implant,
/obj/item/implantpad,
/obj/item/implantcase,
/obj/item/implanter,
/obj/item/circuitboard/computer/operating,
/obj/item/stack/sheet/mineral/silver,
/obj/item/organ_storage
))
/* First aid storage
* Contains:
* First Aid Kits
* Pill Bottles
* Dice Pack (in a pill bottle)
*/
/*
* First Aid Kits
*/
/obj/item/storage/firstaid
name = "first-aid kit"
desc = "It's an emergency medical kit for those serious boo-boos."
icon_state = "firstaid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 3
throw_range = 7
var/empty = FALSE
/obj/item/storage/firstaid/regular
icon_state = "firstaid"
desc = "A first aid kit with the ability to heal common types of injuries."
/obj/item/storage/firstaid/regular/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins giving [user.p_them()]self aids with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/storage/firstaid/regular/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/ancient
icon_state = "firstaid"
desc = "A first aid kit with the ability to heal common types of injuries."
/obj/item/storage/firstaid/ancient/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
/obj/item/storage/firstaid/fire
name = "burn treatment kit"
desc = "A specialized medical kit for when the toxins lab <i>-spontaneously-</i> burns down."
icon_state = "ointment"
item_state = "firstaid-ointment"
/obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!</span>")
return FIRELOSS
/obj/item/storage/firstaid/fire/Initialize(mapload)
. = ..()
icon_state = pick("ointment","firefirstaid")
/obj/item/storage/firstaid/fire/PopulateContents()
if(empty)
return
for(var/i in 1 to 3)
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
new /obj/item/reagent_containers/pill/oxandrolone(src)
new /obj/item/reagent_containers/pill/oxandrolone(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/toxin
name = "toxin treatment kit"
desc = "Used to treat toxic blood content and radiation poisoning."
icon_state = "antitoxin"
item_state = "firstaid-toxin"
/obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return TOXLOSS
/obj/item/storage/firstaid/toxin/Initialize(mapload)
. = ..()
icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
/obj/item/storage/firstaid/toxin/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/syringe/charcoal(src)
for(var/i in 1 to 2)
new /obj/item/storage/pill_bottle/charcoal(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/radbgone
name = "radiation treatment kit"
desc = "Used to treat minor toxic blood content and major radiation poisoning."
icon_state = "antitoxin"
item_state = "firstaid-toxin"
/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return TOXLOSS
/obj/item/storage/firstaid/radbgone/PopulateContents()
if(empty)
return
if(prob(50))
new /obj/item/reagent_containers/pill/mutarad(src)
if(prob(80))
new /obj/item/reagent_containers/pill/antirad_plus(src)
new /obj/item/reagent_containers/syringe/charcoal(src)
new /obj/item/storage/pill_bottle/charcoal(src)
new /obj/item/reagent_containers/pill/mutadone(src)
new /obj/item/reagent_containers/pill/antirad(src)
new /obj/item/reagent_containers/food/drinks/bottle/vodka(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/o2
name = "oxygen deprivation treatment kit"
desc = "A box full of oxygen goodies."
icon_state = "o2"
item_state = "firstaid-o2"
/obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/storage/firstaid/o2/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/pill/salbutamol(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/brute
name = "brute trauma treatment kit"
desc = "A first aid kit for when you get toolboxed."
icon_state = "brute"
item_state = "firstaid-brute"
/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/storage/firstaid/brute/PopulateContents()
if(empty)
return
for(var/i in 1 to 4)
new /obj/item/reagent_containers/pill/patch/styptic(src)
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/gauze(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/tactical
name = "combat medical kit"
desc = "I hope you've got insurance."
icon_state = "bezerk"
/obj/item/storage/firstaid/tactical/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/firstaid/tactical/PopulateContents()
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/defibrillator/compact/combat/loaded(src)
new /obj/item/reagent_containers/hypospray/combat(src)
new /obj/item/reagent_containers/pill/patch/styptic(src)
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
new /obj/item/reagent_containers/syringe/lethal/choral(src)
new /obj/item/clothing/glasses/hud/health/night(src)
/*
* Pill Bottles
*/
/obj/item/storage/pill_bottle
name = "pill bottle"
desc = "It's an airtight container for storing medication."
icon_state = "pill_canister"
icon = 'icons/obj/chemical.dmi'
item_state = "contsolid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
/obj/item/storage/pill_bottle/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.allow_quick_gather = TRUE
STR.click_gather = TRUE
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
/obj/item/storage/pill_bottle/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (TOXLOSS)
/obj/item/storage/pill_bottle/charcoal
name = "bottle of charcoal pills"
desc = "Contains pills used to counter toxins."
/obj/item/storage/pill_bottle/charcoal/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/charcoal(src)
/obj/item/storage/pill_bottle/antirad
name = "bottle of charcoal pills"
desc = "Contains pills used to counter radiation poisoning."
/obj/item/storage/pill_bottle/anitrad/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/antirad(src)
/obj/item/storage/pill_bottle/epinephrine
name = "bottle of epinephrine pills"
desc = "Contains pills used to stabilize patients."
/obj/item/storage/pill_bottle/epinephrine/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/epinephrine(src)
/obj/item/storage/pill_bottle/mutadone
name = "bottle of mutadone pills"
desc = "Contains pills used to treat genetic abnormalities."
/obj/item/storage/pill_bottle/mutadone/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mutadone(src)
/obj/item/storage/pill_bottle/mannitol
name = "bottle of mannitol pills"
desc = "Contains pills used to treat brain damage."
/obj/item/storage/pill_bottle/mannitol/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mannitol(src)
/obj/item/storage/pill_bottle/stimulant
name = "bottle of stimulant pills"
desc = "Guaranteed to give you that extra burst of energy during a long shift!"
/obj/item/storage/pill_bottle/stimulant/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/stimulant(src)
/obj/item/storage/pill_bottle/mining
name = "bottle of patches"
desc = "Contains patches used to treat brute and burn damage."
/obj/item/storage/pill_bottle/mining/PopulateContents()
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/pill/patch/styptic(src)
/obj/item/storage/pill_bottle/zoom
name = "suspicious pill bottle"
desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds."
/obj/item/storage/pill_bottle/zoom/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/zoom(src)
/obj/item/storage/pill_bottle/happy
name = "suspicious pill bottle"
desc = "There is a smiley on the top."
/obj/item/storage/pill_bottle/happy/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/happy(src)
/obj/item/storage/pill_bottle/lsd
name = "suspicious pill bottle"
desc = "There is a badly drawn thing with the shape of a mushroom."
/obj/item/storage/pill_bottle/lsd/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/lsd(src)
/obj/item/storage/pill_bottle/aranesp
name = "suspicious pill bottle"
desc = "The label says 'gotta go fast'."
/obj/item/storage/pill_bottle/aranesp/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/aranesp(src)
/obj/item/storage/pill_bottle/psicodine
name = "bottle of psicodine pills"
desc = "Contains pills used to treat mental distress and traumas."
/obj/item/storage/pill_bottle/psicodine/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/psicodine(src)
/obj/item/storage/pill_bottle/happiness
name = "happiness pill bottle"
desc = "The label is long gone, in its place an 'H' written with a marker."
/obj/item/storage/pill_bottle/happiness/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/happiness(src)
/obj/item/storage/pill_bottle/antirad_plus
name = "anti radiation deluxe pill bottle"
desc = "The label says 'Med-Co branded pills'."
/obj/item/storage/pill_bottle/antirad_plus/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/antirad_plus(src)
/obj/item/storage/pill_bottle/mutarad
name = "radiation treatment deluxe pill bottle"
desc = "The label says 'Med-Co branded pills' and below that 'Contains Mutadone in each pill!`."
/obj/item/storage/pill_bottle/mutarad/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/mutarad(src)
/obj/item/storage/pill_bottle/penis_enlargement
name = "penis enlargement pills"
desc = "You want penis enlargement pills?"
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/penis_enlargement(src)
/obj/item/storage/pill_bottle/breast_enlargement
name = "breast enlargement pills"
desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time."
/obj/item/storage/pill_bottle/breast_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/breast_enlargement(src)
/////////////
//Organ Box//
/////////////
/obj/item/storage/belt/organbox
name = "Organ Storge"
desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying"
w_class = WEIGHT_CLASS_BULKY
icon = 'icons/obj/mysterybox.dmi'
icon_state = "organbox_open"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 1
throw_range = 1
/obj/item/storage/belt/organbox/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 16
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
STR.can_hold = typecacheof(list(
/obj/item/storage/pill_bottle,
/obj/item/reagent_containers/hypospray,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/syringe,
/obj/item/clothing/glasses/hud/health,
/obj/item/hemostat,
/obj/item/scalpel,
/obj/item/retractor,
/obj/item/cautery,
/obj/item/surgical_drapes,
/obj/item/autosurgeon,
/obj/item/organ,
/obj/item/implant,
/obj/item/implantpad,
/obj/item/implantcase,
/obj/item/implanter,
/obj/item/circuitboard/computer/operating,
/obj/item/stack/sheet/mineral/silver,
/obj/item/organ_storage
))
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -655,15 +655,15 @@
if(H.stat == DEAD)
to_chat(user,"<span class='warning'>Only a revive rune can bring back the dead!</span>")
return
if(H.blood_volume < BLOOD_VOLUME_SAFE)
var/restore_blood = BLOOD_VOLUME_SAFE - H.blood_volume
if(H.blood_volume < (BLOOD_VOLUME_SAFE*H.blood_ratio))
var/restore_blood = (BLOOD_VOLUME_SAFE*H.blood_ratio) - H.blood_volume
if(uses*2 < restore_blood)
H.blood_volume += uses*2
to_chat(user,"<span class='danger'>You use the last of your blood rites to restore what blood you could!</span>")
uses = 0
return ..()
else
H.blood_volume = BLOOD_VOLUME_SAFE
H.blood_volume = (BLOOD_VOLUME_SAFE*H.blood_ratio)
uses -= round(restore_blood/2)
to_chat(user,"<span class='warning'>Your blood rites have restored [H == user ? "your" : "[H.p_their()]"] blood to safe levels!</span>")
var/overall_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss()
@@ -698,7 +698,7 @@
if(H.cultslurring)
to_chat(user,"<span class='danger'>[H.p_their(TRUE)] blood has been tainted by an even stronger form of blood magic, it's no use to us like this!</span>")
return
if(H.blood_volume > BLOOD_VOLUME_SAFE)
if(H.blood_volume > (BLOOD_VOLUME_SAFE*H.blood_ratio))
H.blood_volume -= 100
uses += 50
user.Beam(H,icon_state="drainbeam",time=10)
@@ -799,4 +799,4 @@
to_chat(user, "<span class='cultlarge'><b>Your hands glow with POWER OVERWHELMING!!!</b></span>")
else
to_chat(user, "<span class='cultitalic'>You need a free hand for this rite!</span>")
qdel(rite)
qdel(rite)
@@ -188,7 +188,7 @@
var/mob/living/simple_animal/M = L
if(M.health < M.maxHealth)
M.adjustHealth(-3)
if(ishuman(L) && L.blood_volume < BLOOD_VOLUME_NORMAL)
if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
L.blood_volume += 1.0
CHECK_TICK
if(last_corrupt <= world.time)
@@ -27,6 +27,7 @@
var/mob/living/L = owner
L.remove_status_effect(STATUS_EFFECT_INLOVE)
/datum/antagonist/valentine/greet()
to_chat(owner, "<span class='warning'><B>You're on a date with [date.name]! Protect [date.p_them()] at all costs. This takes priority over all other loyalties.</B></span>")
@@ -42,4 +43,21 @@
if(objectives_complete)
return "<span class='greentext big'>[owner.name] protected [owner.p_their()] date</span>"
else
return "<span class='redtext big'>[owner.name] date failed!</span>"
return "<span class='redtext big'>[owner.name] date failed!</span>"
//Just so it's distinct, basically.
/datum/antagonist/valentine/chem/greet()
to_chat(owner, "<span class='warning'><B>You're in love with [date.name]! Protect [date.p_them()] at all costs. This takes priority over all other loyalties.</B></span>")
/datum/antagonist/valentine/chem/roundend_report()
var/objectives_complete = TRUE
if(owner.objectives.len)
for(var/datum/objective/objective in owner.objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
if(objectives_complete)
return "<span class='greentext big'>[owner.name] protected [owner.p_their()] love: [date.name]! <i>What a cutie!</i></span>"
else
return "<span class='redtext big'>[owner.name] date failed!</span>"
+50 -2
View File
@@ -12,6 +12,7 @@
crit_fail = FALSE //Is the flash burnt out?
light_color = LIGHT_COLOR_WHITE
light_power = FLASH_LIGHT_POWER
var/flashing_overlay = "flash-f"
var/times_used = 0 //Number of times it's been used.
var/burnout_resistance = 0
var/last_used = 0 //last world.time it was used.
@@ -36,8 +37,8 @@
add_overlay("flashburnt")
attached_overlays += "flashburnt"
if(flash)
add_overlay("flash-f")
attached_overlays += "flash-f"
add_overlay(flashing_overlay)
attached_overlays += flashing_overlay
addtimer(CALLBACK(src, .proc/update_icon), 5)
if(holder)
holder.update_icon()
@@ -313,3 +314,50 @@
/obj/item/assembly/flash/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
activate()
return ..()
//ported from tg - check to make sure it can't appear where it's not supposed to.
/obj/item/assembly/flash/hypnotic
desc = "A modified flash device, programmed to emit a sequence of subliminal flashes that can send a vulnerable target into a hypnotic trance."
flashing_overlay = "flash-hypno" //I cannot find this icon no matter how hard I look in tg, so I might just make my own.
light_color = LIGHT_COLOR_PINK
cooldown = 20
/obj/item/assembly/flash/hypnotic/burn_out()
return
/obj/item/assembly/flash/hypnotic/flash_carbon(mob/living/carbon/M, mob/user, power = 15, targeted = TRUE, generic_message = FALSE)
if(!istype(M))
return
if(user)
log_combat(user, M, "[targeted? "hypno-flashed(targeted)" : "hypno-flashed(AOE)"]", src)
else //caused by emp/remote signal
M.log_message("was [targeted? "hypno-flashed(targeted)" : "hypno-flashed(AOE)"]",LOG_ATTACK)
if(generic_message && M != user)
to_chat(M, "<span class='disarm'>[src] emits a soothing light...</span>")
if(targeted)
if(M.flash_act(1, 1))
var/hypnosis = FALSE
if(M.hypnosis_vulnerable())
hypnosis = TRUE
if(user)
user.visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>", "<span class='danger'>You hypno-flash [M]!</span>")
if(!hypnosis)
to_chat(M, "<span class='notice'>The light makes you feel oddly relaxed...</span>")
M.confused += min(M.confused + 10, 20)
M.dizziness += min(M.dizziness + 10, 20)
M.drowsyness += min(M.drowsyness + 10, 20)
M.apply_status_effect(STATUS_EFFECT_PACIFY, 100)
else
M.apply_status_effect(/datum/status_effect/trance, 200, TRUE)
else if(user)
user.visible_message("<span class='disarm'>[user] fails to blind [M] with the flash!</span>", "<span class='warning'>You fail to hypno-flash [M]!</span>")
else
to_chat(M, "<span class='danger'>[src] fails to blind you!</span>")
else if(M.flash_act())
to_chat(M, "<span class='notice'>Such a pretty light...</span>")
M.confused += min(M.confused + 4, 20)
M.dizziness += min(M.dizziness + 4, 20)
M.drowsyness += min(M.drowsyness + 4, 20)
+3
View File
@@ -786,6 +786,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Lewdchem:</b><a href='?_src_=prefs;preference=lewdchem'>[lewdchem == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
@@ -1946,6 +1947,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["genitals_use_skintone"] = !features["genitals_use_skintone"]
if("arousable")
arousable = !arousable
if("lewdchem")
lewdchem = !lewdchem
if("has_cock")
features["has_cock"] = !features["has_cock"]
if(features["has_cock"] == FALSE)
@@ -170,6 +170,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["widescreenpref"] >> widescreenpref
S["autostand"] >> autostand
S["cit_toggles"] >> cit_toggles
S["lewdchem"] >> lewdchem
//try to fix any outdated data if necessary
if(needs_update >= 0)
@@ -264,6 +265,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["widescreenpref"], widescreenpref)
WRITE_FILE(S["autostand"], autostand)
WRITE_FILE(S["cit_toggles"], cit_toggles)
WRITE_FILE(S["lewdchem"], lewdchem)
return 1
+9 -4
View File
@@ -41,11 +41,16 @@
else
L.mind.add_antag_datum(/datum/antagonist/heartbreaker)
/proc/forge_valentines_objective(mob/living/lover,mob/living/date)
/proc/forge_valentines_objective(mob/living/lover,mob/living/date,var/chemLove = FALSE)
lover.mind.special_role = "valentine"
var/datum/antagonist/valentine/V = new
V.date = date.mind
lover.mind.add_antag_datum(V) //These really should be teams but i can't be assed to incorporate third wheels right now
if (chemLove == TRUE)
var/datum/antagonist/valentine/chem/V = new //Changes text and EOG check basically.
V.date = date.mind
lover.mind.add_antag_datum(V)
else
var/datum/antagonist/valentine/V = new
V.date = date.mind
lover.mind.add_antag_datum(V) //These really should be teams but i can't be assed to incorporate third wheels right now
/datum/round_event/valentines/announce(fake)
priority_announce("It's Valentine's Day! Give a valentine to that special someone!")
@@ -7,7 +7,7 @@
desc = "Nougat love it or hate it."
icon_state = "candy"
trash = /obj/item/trash/candy
list_reagents = list("nutriment" = 1, "sugar" = 3)
list_reagents = list("nutriment" = 1, "sugar" = 3, "cocoa" = 3)
junkiness = 25
filling_color = "#D2691E"
tastes = list("candy" = 1)
@@ -404,6 +404,31 @@ h1.alert, h2.alert {color: #99aab5;}
.redtext {color: #c51e1e; font-size: 24px;}
.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
0% { color: #400020; }
40% { color: #FF0000; }
50% { color: #FF8888; }
60% { color: #FF0000; }
100% { color: #400020; }
}
.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;}
@keyframes hypnocolor {
0% { color: #202020; }
25% { color: #4b02ac; }
50% { color: #9f41f1; }
75% { color: #541c9c; }
100% { color: #7adbf3; }
}
.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;}
@keyframes phobia {
0% { color: #f75a5a; }
50% { color: #dd0000; }
100% { color: #f75a5a; }
}
.icon {height: 1em; width: auto;}
+49 -11
View File
@@ -18,10 +18,10 @@
/mob/living/carbon/monkey/handle_blood()
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL)
if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio))
blood_volume += 0.1 // regenerate blood VERY slowly
if(blood_volume < BLOOD_VOLUME_OKAY)
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
if(blood_volume < (BLOOD_VOLUME_OKAY * blood_ratio))
adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1))
// Takes care blood loss and regeneration
/mob/living/carbon/human/handle_blood()
@@ -33,7 +33,7 @@
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER))
if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio) && !HAS_TRAIT(src, TRAIT_NOHUNGER))
var/nutrition_ratio = 0
switch(nutrition)
if(0 to NUTRITION_LEVEL_STARVING)
@@ -46,20 +46,22 @@
nutrition_ratio = 0.8
else
nutrition_ratio = 1
if(HAS_TRAIT(src, TRAIT_HIGH_BLOOD))
nutrition_ratio *= 1.2
if(satiety > 80)
nutrition_ratio *= 1.25
nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR)
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
blood_volume = min((BLOOD_VOLUME_NORMAL * blood_ratio), blood_volume + 0.5 * nutrition_ratio)
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
switch(blood_volume)
switch(blood_volume * INVERSE(blood_ratio))
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(5))
to_chat(src, "<span class='warning'>You feel [word].</span>")
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.01, 1))
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1))
if(prob(5))
blur_eyes(6)
to_chat(src, "<span class='warning'>You feel very [word].</span>")
@@ -111,7 +113,7 @@
blood_volume = initial(blood_volume)
/mob/living/carbon/human/restore_blood()
blood_volume = BLOOD_VOLUME_NORMAL
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
bleed_rate = 0
/****************************************************
@@ -122,7 +124,7 @@
/mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced)
if(!blood_volume || !AM.reagents)
return 0
if(blood_volume < BLOOD_VOLUME_BAD && !forced)
if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced)
return 0
if(blood_volume < amount)
@@ -161,7 +163,7 @@
return
/mob/living/carbon/get_blood_data(blood_id)
if(blood_id == "blood") //actual blood reagent
if(blood_id == "blood") //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
@@ -204,6 +206,21 @@
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff.
var/blood_data = list()
if(mind)
blood_data["mind"] = mind
else if(last_mind)
blood_data["mind"] = last_mind
if(ckey)
blood_data["ckey"] = ckey
else if(last_mind)
blood_data["ckey"] = ckey(last_mind.key)
blood_data["gender"] = gender
blood_data["real_name"] = real_name
return blood_data
//get the id of the substance this mob use as blood.
/mob/proc/get_blood_id()
@@ -300,3 +317,24 @@
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
if(!B)
B = new(T)
//This is a terrible way of handling it.
/mob/living/proc/ResetBloodVol()
if(ishuman(src))
var/mob/living/carbon/human/H = src
if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD))
blood_ratio = 1.2
H.handle_blood()
return
blood_ratio = 1
H.handle_blood()
return
blood_ratio = 1
/mob/living/proc/AdjustBloodVol(var/value)
if(blood_ratio == value)
return
blood_ratio = value
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.handle_blood()
+18 -1
View File
@@ -6,6 +6,7 @@
create_reagents(1000)
update_body_parts() //to update the carbon's new bodyparts appearance
GLOB.carbon_list += src
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
/mob/living/carbon/Destroy()
//This must be done first, so the mob ghosts correctly before DNA etc is nulled
@@ -477,11 +478,13 @@
if(message)
visible_message("<span class='danger'>[src] throws up all over [p_them()]self!</span>", \
"<span class='userdanger'>You throw up all over yourself!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "vomit", /datum/mood_event/vomitself)
distance = 0
else
if(message)
visible_message("<span class='danger'>[src] throws up!</span>", "<span class='userdanger'>You throw up!</span>")
if(!isflyperson(src))
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "vomit", /datum/mood_event/vomit)
if(stun)
Stun(80)
@@ -929,3 +932,17 @@
/mob/living/carbon/can_resist()
return bodyparts.len > 2 && ..()
/mob/living/carbon/proc/hypnosis_vulnerable()//unused atm, but added in case
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
return FALSE
if(hallucinating())
return TRUE
if(IsSleeping())
return TRUE
if(HAS_TRAIT(src, TRAIT_DUMB))
return TRUE
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
if(mood)
if(mood.sanity < SANITY_UNSTABLE)
return TRUE
@@ -247,7 +247,7 @@
if(DISGUST_LEVEL_DISGUSTED to INFINITY)
msg += "[t_He] look[p_s()] extremely disgusted.\n"
if(blood_volume < BLOOD_VOLUME_SAFE)
if(blood_volume < (BLOOD_VOLUME_SAFE*blood_ratio))
msg += "[t_He] [t_has] pale skin.\n"
if(bleedsuppress)
@@ -281,6 +281,13 @@
if(91.01 to INFINITY)
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
if(reagents.has_reagent("astral"))
msg += "[t_He] have wild, spacey eyes"
if(mind)
msg += " and have a strange, abnormal look to them.\n"
else
msg += " and don't look like they're all there.\n"
if(isliving(user))
var/mob/living/L = user
if(src != user && HAS_TRAIT(L, TRAIT_EMPATH) && !appears_dead)
@@ -304,6 +311,13 @@
msg += "</span>"
var/obj/item/organ/vocal_cords/Vc = user.getorganslot(ORGAN_SLOT_VOICE)
if(Vc)
if(istype(Vc, /obj/item/organ/vocal_cords/velvet))
if(client?.prefs.lewdchem)
msg += "<span class='velvet'><i>You feel your chords resonate looking at them.</i></span>\n"
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n"
@@ -812,6 +812,8 @@
for(var/datum/mutation/human/HM in dna.mutations)
if(HM.quality != POSITIVE)
dna.remove_mutation(HM.name)
if(blood_volume < (BLOOD_VOLUME_NORMAL*blood_ratio))
blood_volume = (BLOOD_VOLUME_NORMAL*blood_ratio)
..()
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
@@ -48,6 +48,7 @@
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
var/name_override //For temporary visible name changes
var/genital_override = FALSE //Force genitals on things incase of chems
var/nameless = FALSE //For drones of both the insectoid and robotic kind. And other types of nameless critters.
@@ -48,14 +48,14 @@
H.adjustBruteLoss(5)
to_chat(H, "<span class='danger'>You feel empty!</span>")
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio))
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
H.blood_volume += 3
H.nutrition -= 2.5
if(H.blood_volume < BLOOD_VOLUME_OKAY)
if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio))
if(prob(5))
to_chat(H, "<span class='danger'>You feel drained!</span>")
if(H.blood_volume < BLOOD_VOLUME_BAD)
if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio))
Cannibalize_Body(H)
if(regenerate_limbs)
regenerate_limbs.UpdateButtonIcon()
@@ -87,7 +87,7 @@
var/list/limbs_to_heal = H.get_missing_limbs()
if(limbs_to_heal.len < 1)
return 0
if(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
if(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40)
return 1
return 0
@@ -98,13 +98,13 @@
to_chat(H, "<span class='notice'>You feel intact enough as it is.</span>")
return
to_chat(H, "<span class='notice'>You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...</span>")
if(H.blood_volume >= 40*limbs_to_heal.len+BLOOD_VOLUME_OKAY)
if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio))
H.regenerate_limbs()
H.blood_volume -= 40*limbs_to_heal.len
to_chat(H, "<span class='notice'>...and after a moment you finish reforming!</span>")
return
else if(H.blood_volume >= 40)//We can partially heal some limbs
while(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40)
var/healed_limb = pick(limbs_to_heal)
H.regenerate_limb(healed_limb)
limbs_to_heal -= healed_limb
@@ -138,7 +138,7 @@
bodies -= C // This means that the other bodies maintain a link
// so if someone mindswapped into them, they'd still be shared.
bodies = null
C.blood_volume = min(C.blood_volume, BLOOD_VOLUME_NORMAL)
C.blood_volume = min(C.blood_volume, (BLOOD_VOLUME_NORMAL*C.blood_ratio))
..()
/datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species)
@@ -729,4 +729,4 @@
to_chat(H, "<span class='notice'>You connect [target]'s mind to your slime link!</span>")
else
to_chat(H, "<span class='warning'>You can't seem to link [target]'s mind...</span>")
to_chat(target, "<span class='warning'>The foreign presence leaves your mind.</span>")
to_chat(target, "<span class='warning'>The foreign presence leaves your mind.</span>")
@@ -46,7 +46,7 @@
C.adjustCloneLoss(-4)
return
C.blood_volume -= 0.75
if(C.blood_volume <= BLOOD_VOLUME_SURVIVE)
if(C.blood_volume <= (BLOOD_VOLUME_SURVIVE*C.blood_ratio))
to_chat(C, "<span class='danger'>You ran out of blood!</span>")
C.dust()
var/area/A = get_area(C)
@@ -88,4 +88,4 @@
AM.Hear(rendered, src, language, message, , spans)
if(critical) //Dying words.
succumb(1)
succumb()
+8
View File
@@ -229,6 +229,9 @@
else if(SA_partialpressure > 0.01)
if(prob(20))
emote(pick("giggle","laugh"))
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "chemical_euphoria", /datum/mood_event/chemical_euphoria)
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
//BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz])
@@ -527,6 +530,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(jitteriness)
do_jitter_animation(jitteriness)
jitteriness = max(jitteriness - restingpwr, 0)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "jittery", /datum/mood_event/jittery)
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "jittery")
if(stuttering)
stuttering = max(stuttering-1, 0)
@@ -612,6 +618,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(drunkenness >= 101)
adjustToxLoss(4) //Let's be honest you shouldn't be alive by now
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk")
//used in human and monkey handle_environment()
/mob/living/carbon/proc/natural_bodytemperature_stabilization()
+15 -5
View File
@@ -318,17 +318,27 @@
visible_message("<b>[src]</b> points at [A].", "<span class='notice'>You point at [A].</span>")
return TRUE
/mob/living/verb/succumb(whispered as null)
/mob/living/verb/succumb()
set name = "Succumb"
set category = "IC"
if(src.has_status_effect(/datum/status_effect/chem/enthrall))
var/datum/status_effect/chem/enthrall/E = src.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase < 3)
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
to_chat(src, "<span class='notice'>Your mindshield prevents your mind from giving in!</span>")
else if(src.mind.assigned_role in GLOB.command_positions)
to_chat(src, "<span class='notice'>Your dedication to your department prevents you from giving in!</span>")
else
E.enthrallTally += 20
to_chat(src, "<span class='notice'>You give into [E.master]'s influence.</span>")
if (InCritical())
log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", LOG_ATTACK)
log_message("Has succumbed to death while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", LOG_ATTACK)
adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD)
updatehealth()
if(!whispered)
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
death()
/mob/living/incapacitated(ignore_restraints, ignore_grab)
if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here
return TRUE
@@ -532,7 +542,7 @@
var/trail_type = getTrail()
if(trail_type)
var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
if(blood_volume && blood_volume > max(BLOOD_VOLUME_NORMAL*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
if(blood_volume && blood_volume > max((BLOOD_VOLUME_NORMAL*blood_ratio)*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
blood_volume = max(blood_volume - max(1, brute_ratio * 2), 0) //that depends on our brute damage.
var/newdir = get_dir(target_turf, start)
if(newdir != direction)
@@ -77,6 +77,7 @@
var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added
var/blood_volume = 0 //how much blood the mob has
var/blood_ratio = 1 //How much blood the mob needs, in terms of ratio (i.e 1.2 will require BLOOD_VOLUME_NORMAL of 672) DO NOT GO ABOVE 3.55 Well, actually you can but, then they can't get enough blood.
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
var/see_override = 0 //0 for no override, sets see_invisible = see_override in silicon & carbon life process via update_sight()
+2 -1
View File
@@ -211,7 +211,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
send_speech(message, message_range, src, bubble_type, spans, language, message_mode)
if(succumbed)
succumb(1)
succumb()
to_chat(src, compose_message(src, language, message, , spans, message_mode))
return 1
@@ -281,6 +281,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mode)
else
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
//speech bubble
var/list/speech_bubble_recipients = list()
@@ -0,0 +1,59 @@
/mob/living/simple_animal/astral
name = "Astral projection"
desc = "A soul of someone projecting their mind."
icon = 'icons/mob/mob.dmi'
icon_state = "ghost"
icon_living = "ghost"
mob_biotypes = list(MOB_SPIRIT)
attacktext = "raises the hairs on the neck of"
response_harm = "disrupts the concentration of"
response_disarm = "wafts"
friendly = "communes with"
loot = null
maxHealth = 10
health = 10
melee_damage_lower = 0
melee_damage_upper = 0
obj_damage = 0
deathmessage = "disappears as if it was never really there to begin with"
incorporeal_move = 1
alpha = 50
attacktext = "touches the mind of"
speak_emote = list("echos")
movement_type = FLYING
var/pseudo_death = FALSE
var/posses_safe = FALSE
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 0
minbodytemp = 0
maxbodytemp = 100000
/mob/living/simple_animal/astral/death()
icon_state = "shade_dead"
Stun(1000)
canmove = 0
friendly = "deads at"
pseudo_death = TRUE
incorporeal_move = 0
to_chat(src, "<span class='notice'>Your astral projection is interrupted and your mind is sent back to your body with a shock!</span>")
/mob/living/simple_animal/astral/ClickOn(var/atom/A, var/params)
..()
if(pseudo_death == FALSE)
if(isliving(A))
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.reagents.has_reagent("astral") && !H.mind)
var/datum/reagent/fermi/astral/As = locate(/datum/reagent/fermi/astral) in H.reagents.reagent_list
if(As.originalmind == src.mind && As.current_cycle < 10 && H.stat != DEAD) //So you can return to your body.
to_chat(src, "<span class='warning'><b><i>The intensity of the astrogen in your body is too much allow you to return to yourself yet!</b></i></span>")
return
to_chat(src, "<b><i>You astrally possess [H]!</b></i>")
log_game("FERMICHEM: [src] has astrally possessed [A]!")
src.mind.transfer_to(H)
qdel(src)
var/message = html_decode(stripped_input(src, "Enter a message to send to [A]", MAX_MESSAGE_LEN))
if(!message)
return
to_chat(A, "[src] projects into your mind, <b><i> \"[message]\"</b></i>")
log_game("FERMICHEM: [src] has astrally transmitted [message] into [A]")
@@ -292,3 +292,31 @@
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
L.reagents.add_reagent("nutriment", 0.4)
L.reagents.add_reagent("vitamin", 0.4)
//Cat made
/mob/living/simple_animal/pet/cat/custom_cat
name = "White cat" //Incase it somehow gets spawned without an ID
desc = "A cute white catto!"
icon_state = "custom_cat"
icon_living = "custom_cat"
icon_dead = "custom_cat_dead"
gender = FEMALE
gold_core_spawnable = NO_SPAWN
health = 50 //So people can't instakill it s
maxHealth = 50
speak = list("Meowrowr!", "Mew!", "Miauen!")
speak_emote = list("wigglepurrs", "mewls")
emote_hear = list("meows.", "mews.")
emote_see = list("looks at you eagerly for pets!", "wiggles enthusiastically.")
gold_core_spawnable = NO_SPAWN
var/pseudo_death = FALSE
/mob/living/simple_animal/pet/cat/custom_cat/death()
if (pseudo_death == TRUE) //secret cat chem
icon_state = "custom_cat_dead"
Stun(1000)
canmove = 0
friendly = "deads at"
return
else
..()
@@ -55,4 +55,28 @@
/mob/living/simple_animal/hostile/zombie/drop_loot()
. = ..()
corpse.forceMove(drop_location())
corpse.create()
corpse.create()
/mob/living/simple_animal/hostile/unemployedclone
name = "Failed clone"
desc = "Somebody failed chemistry."
icon = 'icons/mob/human.dmi'
icon_state = "husk"
icon_living = "husk"
icon_dead = "husk"
mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
speak_chance = 0
stat_attack = UNCONSCIOUS //braains
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 21
melee_damage_upper = 21
attacktext = "bites"
attack_sound = 'sound/hallucinations/growl1.ogg'
a_intent = INTENT_HARM
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
spacewalk = FALSE
status_flags = CANPUSH
del_on_death = 0
+29
View File
@@ -32,4 +32,33 @@
last_taste_time = world.time
last_taste_text = text_output
//FermiChem - How to check pH of a beaker without a meter/pH paper.
//Basically checks the pH of the holder and burns your poor tongue if it's too acidic!
//TRAIT_AGEUSIA players can't taste, unless it's burning them.
//taking sips of a strongly acidic/alkaline substance will burn your tongue.
/mob/living/carbon/taste(datum/reagents/from)
var/obj/item/organ/tongue/T = getorganslot("tongue")
if (!T)
return
.=..()
if ((from.pH > 12.5) || (from.pH < 1.5))
to_chat(src, "<span class='warning'>You taste chemical burns!</span>")
T.adjustTongueLoss(src, 4)
if(istype(T, /obj/item/organ/tongue/cybernetic))
to_chat(src, "<span class='notice'>Your tongue moves on it's own in response to the liquid.</span>")
say("The pH is appropriately [round(from.pH, 1)].")
return
if (!HAS_TRAIT(src, TRAIT_AGEUSIA)) //I'll let you get away with not having 1 damage.
switch(from.pH)
if(11.5 to INFINITY)
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
T.adjustTongueLoss(src, 1)
if(8.5 to 11.5)
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
if(2.5 to 5.5)
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
if(-INFINITY to 2.5)
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
T.adjustTongueLoss(src, 1)
#undef DEFAULT_TASTE_SENSITIVITY
+339 -46
View File
@@ -1,4 +1,3 @@
/proc/build_chemical_reagent_list()
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
@@ -53,10 +52,16 @@
var/maximum_volume = 100
var/atom/my_atom = null
var/chem_temp = 150
var/pH = REAGENT_NORMAL_PH//Potential of hydrogen. Edited on adding new reagents, deleting reagents, and during fermi reactions.
var/overallPurity = 1
var/last_tick = 1
var/addiction_tick = 1
var/list/datum/reagent/addiction_list = new/list()
var/reagents_holder_flags
var/targetVol = 0 //the target volume, i.e. the total amount that can be created during a fermichem reaction.
var/reactedVol = 0 //how much of the reagent is reacted during a fermireaction
var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.)
var/fermiReactID = null //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs.
/datum/reagents/New(maximum=100, new_flags)
maximum_volume = maximum
@@ -121,11 +126,13 @@
/datum/reagents/proc/remove_all(amount = 1)
var/list/cached_reagents = reagent_list
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
pH = 7
if(total_volume > 0)
var/part = amount / total_volume
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
remove_reagent(R.id, R.volume * part)
remove_reagent(R.id, R.volume * part, ignore_pH = TRUE)
update_total()
handle_reactions()
@@ -189,8 +196,11 @@
var/transfer_amount = T.volume * part
if(preserve_data)
trans_data = copy_data(T)
R.add_reagent(T.id, transfer_amount * multiplier, trans_data, chem_temp, no_react = 1) //we only handle reaction after every reagent has been transfered.
remove_reagent(T.id, transfer_amount)
R.add_reagent(T.id, transfer_amount * multiplier, trans_data, chem_temp, T.purity, pH, no_react = TRUE, ignore_pH = TRUE) //we only handle reaction after every reagent has been transfered.
remove_reagent(T.id, transfer_amount, ignore_pH = TRUE)
update_total()
R.update_total()
@@ -249,7 +259,8 @@
if(current_reagent.id == reagent)
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, amount, trans_data, src.chem_temp)
R.add_reagent(current_reagent.id, amount, trans_data, chem_temp, current_reagent.purity, pH, no_react = TRUE)
remove_reagent(current_reagent.id, amount, 1)
break
@@ -350,14 +361,21 @@
R.on_update (A)
update_total()
/datum/reagents/proc/handle_reactions()
/datum/reagents/proc/handle_reactions()//HERE EDIT HERE THE MAIN REACTION
if(fermiIsReacting == TRUE)
return
if(reagents_holder_flags & NO_REACT)
return //Yup, no reactions here. No siree.
var/list/cached_reagents = reagent_list
var/list/cached_reactions = GLOB.chemical_reactions_list
var/datum/cached_my_atom = my_atom
var/reaction_occurred = 0
var/reaction_occurred = 0 // checks if reaction, binary variable
var/continue_reacting = FALSE //Helps keep track what kind of reaction is occuring; standard or fermi.
do
var/list/possible_reactions = list()
reaction_occurred = 0
@@ -382,6 +400,7 @@
var/has_special_react = C.special_react
var/can_special_react = 0
for(var/B in cached_required_reagents)
if(!has_reagent(B, cached_required_reagents[B]))
break
@@ -402,7 +421,7 @@
if(!C.required_other)
matching_other = 1
else if(istype(cached_my_atom, /obj/item/slime_extract))
else if(istype(cached_my_atom, /obj/item/slime_extract))//if the object is a slime_extract.
var/obj/item/slime_extract/M = cached_my_atom
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
@@ -413,7 +432,7 @@
if(!C.required_other)
matching_other = 1
if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))
if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))//Temperature check!!
meets_temp_requirement = 1
if(!has_special_react || C.check_special_react(src))
@@ -427,53 +446,268 @@
//select the reaction with the most extreme temperature requirements
for(var/V in possible_reactions)
var/datum/chemical_reaction/competitor = V
if(selected_reaction.is_cold_recipe) //if there are no recipe conflicts, everything in possible_reactions will have this same value for is_cold_reaction. warranty void if assumption not met.
if(selected_reaction.is_cold_recipe)
if(competitor.required_temp <= selected_reaction.required_temp)
selected_reaction = competitor
else
if(competitor.required_temp >= selected_reaction.required_temp)
if(competitor.required_temp >= selected_reaction.required_temp) //will return with the hotter reacting first.
selected_reaction = competitor
var/list/cached_required_reagents = selected_reaction.required_reagents
var/list/cached_results = selected_reaction.results
var/list/cached_required_reagents = selected_reaction.required_reagents//update reagents list
var/list/cached_results = selected_reaction.results//resultant chemical list
var/special_react_result = selected_reaction.check_special_react(src)
var/list/multiplier = INFINITY
for(var/B in cached_required_reagents)
multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B]))
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1)
//Splits reactions into two types; FermiChem is advanced reaction mechanics, Other is default reaction.
//FermiChem relies on two additional properties; pH and impurity
//Temperature plays into a larger role too.
var/datum/chemical_reaction/C = selected_reaction
for(var/P in selected_reaction.results)
multiplier = max(multiplier, 1) //this shouldnt happen ...
SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*multiplier, P)
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
if (C.FermiChem == TRUE && !continue_reacting)
if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions.
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion"))
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
return 0
var/list/seen = viewers(4, get_turf(my_atom))
var/iconhtml = icon2html(cached_my_atom, seen)
if(cached_my_atom)
if(!ismob(cached_my_atom)) // No bubbling mobs
if(selected_reaction.mix_sound)
playsound(get_turf(cached_my_atom), selected_reaction.mix_sound, 80, 1)
for(var/B in cached_required_reagents)
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.01))
for(var/P in selected_reaction.results)
targetVol = cached_results[P]*multiplier
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] [selected_reaction.mix_message]</span>")
if( (chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin))
if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )//To prevent pointless reactions
if (fermiIsReacting == TRUE)
return 0
else
START_PROCESSING(SSprocessing, src)
selected_reaction.on_reaction(src, my_atom, multiplier)
fermiIsReacting = TRUE
fermiReactID = selected_reaction
reaction_occurred = 1
else //It's a little bit of a confusing nest, but esstentially we check if it's a fermireaction, then temperature, then pH. If this is true, the remainer of this handler is run.
return 0 //If pH is out of range
else
return 0 //If not hot enough
//Standard reaction mechanics:
else
if (C.FermiChem == TRUE)//Just to make sure
return 0
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.01))
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE)
for(var/P in selected_reaction.results)
multiplier = max(multiplier, 1) //this shouldnt happen ...
SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*multiplier, P)//log
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
var/list/seen = viewers(4, get_turf(my_atom))//Sound and sight checkers
var/iconhtml = icon2html(cached_my_atom, seen)
if(cached_my_atom)
if(!ismob(cached_my_atom)) // No bubbling mobs
if(selected_reaction.mix_sound)
playsound(get_turf(cached_my_atom), selected_reaction.mix_sound, 80, 1)
if(istype(cached_my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [my_atom]'s power is consumed in the reaction.</span>")
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
to_chat(M, "<span class='notice'>[iconhtml] [selected_reaction.mix_message]</span>")
selected_reaction.on_reaction(src, multiplier, special_react_result)
reaction_occurred = 1
if(istype(cached_my_atom, /obj/item/slime_extract))//if there's an extract and it's used up.
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [my_atom]'s power is consumed in the reaction.</span>")
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
selected_reaction.on_reaction(src, multiplier, special_react_result)
reaction_occurred = 1
continue_reacting = TRUE
while(reaction_occurred)
update_total()
return 0
/datum/reagents/process()
var/datum/chemical_reaction/fermi/C = fermiReactID
var/list/cached_required_reagents = C.required_reagents//update reagents list
var/list/cached_results = C.results//resultant chemical list
var/multiplier = INFINITY
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.001))
if (multiplier == 0)
fermiEnd()
return
for(var/P in cached_results)
targetVol = cached_results[P]*multiplier
if (fermiIsReacting == FALSE)
CRASH("Fermi has refused to stop reacting even though we asked her nicely.")
if (chem_temp > C.OptimalTempMin && fermiIsReacting == TRUE)//To prevent pointless reactions
if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )
if (reactedVol < targetVol)
reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
else//Volume is used up
fermiEnd()
return
else//pH is out of range
fermiEnd()
return
else//Temperature is too low, or reaction has stopped.
fermiEnd()
return
/datum/reagents/proc/fermiEnd()
var/datum/chemical_reaction/fermi/C = fermiReactID
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
reactedVol = 0
targetVol = 0
//pH check, handled at the end to reduce calls.
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()
C.FermiFinish(src, my_atom)
handle_reactions()
update_total()
//Reaction sounds and words
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
var/list/seen = viewers(5, get_turf(my_atom))
var/iconhtml = icon2html(my_atom, seen)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] [C.mix_message]</span>")
/datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
var/datum/chemical_reaction/fermi/C = selected_reaction
var/deltaT = 0
var/deltapH = 0
var/stepChemAmmount = 0
//get purity from combined beaker reactant purities HERE.
var/purity = 1
//Begin checks
//For now, purity is handled elsewhere (on add)
//Calculate DeltapH (Deviation of pH from optimal)
//Lower range
if (cached_pH < C.OptimalpHMin)
if (cached_pH < (C.OptimalpHMin - C.ReactpHLim))
deltapH = 0
return//If outside pH range, no reaction
else
deltapH = (((cached_pH - (C.OptimalpHMin - C.ReactpHLim))**C.CurveSharppH)/((C.ReactpHLim**C.CurveSharppH)))
//Upper range
else if (cached_pH > C.OptimalpHMax)
if (cached_pH > (C.OptimalpHMax + C.ReactpHLim))
deltapH = 0
return //If outside pH range, no reaction
else
deltapH = (((- cached_pH + (C.OptimalpHMax + C.ReactpHLim))**C.CurveSharppH)/(C.ReactpHLim**C.CurveSharppH))//Reverse - to + to prevent math operation failures.
//Within mid range
else if (cached_pH >= C.OptimalpHMin && cached_pH <= C.OptimalpHMax)
deltapH = 1
//This should never proc:
else
WARNING("[my_atom] attempted to determine FermiChem pH for '[C.id]' which broke for some reason! ([usr])")
//Calculate DeltaT (Deviation of T from optimal)
if (cached_temp < C.OptimalTempMax && cached_temp >= C.OptimalTempMin)
deltaT = (((cached_temp - C.OptimalTempMin)**C.CurveSharpT)/((C.OptimalTempMax - C.OptimalTempMin)**C.CurveSharpT))
else if (cached_temp >= C.OptimalTempMax)
deltaT = 1
else
deltaT = 0
purity = (deltapH)//set purity equal to pH offset
//Then adjust purity of result with reagent purity.
purity *= reactant_purity(C)
var/removeChemAmmount //remove factor
var/addChemAmmount //add factor
//ONLY WORKS FOR ONE PRODUCT AT THE MOMENT
//Calculate how much product to make and how much reactant to remove factors..
for(var/P in cached_results)
//stepChemAmmount = CLAMP(((deltaT * multiplier), 0, ((targetVol - reactedVol)/cached_results[P])) //used to have multipler, now it does
stepChemAmmount = (multiplier*cached_results[P])
if (stepChemAmmount >= C.RateUpLim)
stepChemAmmount = (C.RateUpLim)
addChemAmmount = deltaT * stepChemAmmount
if (addChemAmmount >= (targetVol - reactedVol))
addChemAmmount = (targetVol - reactedVol)
if (addChemAmmount < 0.01)
addChemAmmount = 0.01
removeChemAmmount = (addChemAmmount/cached_results[P])
//This is kept for future bugtesters.
//message_admins("Reaction vars: PreReacted: [reactedVol] of [targetVol]. deltaT [deltaT], multiplier [multiplier], Step [stepChemAmmount], uncapped Step [deltaT*(multiplier*cached_results[P])], addChemAmmount [addChemAmmount], removeFactor [removeChemAmmount] Pfactor [cached_results[P]], adding [addChemAmmount]")
//remove reactants
for(var/B in cached_required_reagents)
remove_reagent(B, (removeChemAmmount * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE)
//add product
var/TotalStep = 0
for(var/P in cached_results)
SSblackbox.record_feedback("tally", "chemical_reaction", addChemAmmount, P)//log
SSblackbox.record_feedback("tally", "fermi_chem", addChemAmmount, P)
add_reagent(P, (addChemAmmount), null, cached_temp, purity)//add reagent function!! I THINK I can do this:
TotalStep += addChemAmmount//for multiple products
//Above should reduce yeild based on holder purity.
//Purity Check
for(var/datum/reagent/R in my_atom.reagents.reagent_list)
if(P == R.id)
if (R.purity < C.PurityMin)//If purity is below the min, blow it up.
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[P] explosion"))
C.FermiExplode(src, my_atom, (reactedVol+targetVol), cached_temp, pH)
STOP_PROCESSING(SSprocessing, src)
return 0
C.FermiCreate(src)//proc that calls when step is done
//Apply pH changes and thermal output of reaction to beaker
chem_temp = round(cached_temp + (C.ThermicConstant * addChemAmmount))
pH += (C.HIonRelease * addChemAmmount)
//keep track of the current reacted amount
reactedVol = reactedVol + addChemAmmount
//Check extremes
if (chem_temp > C.ExplodeTemp)
//go to explode proc
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[C] explosions"))
C.FermiExplode(src, my_atom, (reactedVol+targetVol), chem_temp, pH)
STOP_PROCESSING(SSprocessing, src)
return
//Make sure things are limited.
pH = CLAMP(pH, 0, 14)
//return said amount to compare for next step.
return (reactedVol)
//Currently calculates it irrespective of required reagents at the start
/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder)
var/list/cached_reagents = reagent_list
var/i = 0
var/cachedPurity
for(var/datum/reagent/R in my_atom.reagents.reagent_list)
if (R in cached_reagents)
cachedPurity += R.purity
i++
return cachedPurity/i
/datum/reagents/proc/isolate_reagent(reagent)
var/list/cached_reagents = reagent_list
for(var/_reagent in cached_reagents)
@@ -517,6 +751,7 @@
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
del_reagent(R.id)
pH = REAGENT_NORMAL_PH
return 0
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
@@ -563,13 +798,17 @@
/datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000)
var/S = specific_heat()
chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), 2.7, 1000)
chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), min_temp, max_temp)
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
RC.temp_check()
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, other_purity = 1, other_pH, no_react = 0, ignore_pH = FALSE)
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
if(!isnum(amount) || !amount)
return FALSE
if(amount <= 0)
if(amount <= 0.00)
return FALSE
var/datum/reagent/D = GLOB.chemical_reagents_list[reagent]
@@ -577,6 +816,23 @@
WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
return FALSE
if (D.id == "water" && no_react == FALSE && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany.
if (pH <= 2)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "water-acid explosions")
var/datum/effect_system/smoke_spread/chem/s = new
var/turf/T = get_turf(my_atom)
var/datum/reagents/R = new/datum/reagents(3000)
R.add_reagent("fermiAcid", amount)
for (var/datum/reagent/reagentgas in reagent_list)
R.add_reagent(reagentgas, amount/5)
remove_reagent(reagentgas, amount/5)
s.set_up(R, CLAMP(amount/10, 0, 2), T)
s.start()
return FALSE
if(!pH)
other_pH = D.pH
update_total()
var/cached_total = total_volume
if(cached_total + amount > maximum_volume)
@@ -587,6 +843,10 @@
var/cached_temp = chem_temp
var/list/cached_reagents = reagent_list
var/cached_pH = pH
//Equalize temperature - Not using specific_heat() because the new chemical isn't in yet.
var/specific_heat = 0
var/thermal_energy = 0
@@ -597,32 +857,55 @@
specific_heat += D.specific_heat * (amount / new_total)
thermal_energy += D.specific_heat * amount * reagtemp
chem_temp = thermal_energy / (specific_heat * new_total)
////
//cacluate reagent based pH shift.
if(ignore_pH == TRUE)
pH = ((cached_pH * cached_total)+(other_pH * amount))/(cached_total + amount)//should be right
else
pH = ((cached_pH * cached_total)+(D.pH * amount))/(cached_total + amount)//should be right
if(istype(my_atom, /obj/item/reagent_containers/))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()//checks beaker resilience
//add the reagent to the existing if it exists
for(var/A in cached_reagents)
var/datum/reagent/R = A
if (R.id == reagent)
if (R.id == reagent) //IF MERGING
//Add amount and equalize purity
R.volume += amount
R.purity = ((R.purity * R.volume) + (other_purity * amount)) /((R.volume + amount)) //This should add the purity to the product
update_total()
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
R.on_merge(data, amount)
if(isliving(my_atom))
if(R.OnMobMergeCheck == TRUE)//Forces on_mob_add proc when a chem is merged
R.on_mob_add(my_atom, amount)
//else
// R.on_merge(data, amount, my_atom, other_purity)
R.on_merge(data, amount, my_atom, other_purity)
if(!no_react)
handle_reactions()
return TRUE
//otherwise make a new one
var/datum/reagent/R = new D.type(data)
cached_reagents += R
R.holder = src
R.volume = amount
R.purity = other_purity
R.loc = get_turf(my_atom)
if(data)
R.data = data
R.on_new(data)
if(R.addProc == TRUE)//Allows on new without data overhead.
R.on_new(pH) //Add more as desired.
if(isliving(my_atom))
R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete
R.on_mob_add(my_atom, amount)
update_total()
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
@@ -630,12 +913,13 @@
handle_reactions()
return TRUE
/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15)
for(var/r_id in list_reagents)
var/amt = list_reagents[r_id]
add_reagent(r_id, amt, data)
/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to
/datum/reagents/proc/remove_reagent(reagent, amount, safety, ignore_pH = FALSE)//Added a safety check for the trans_id_to
if(isnull(amount))
amount = 0
@@ -653,6 +937,15 @@
for(var/A in cached_reagents)
var/datum/reagent/R = A
if (R.id == reagent)
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
pH = 7
//In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people.
else if (ignore_pH == FALSE)
//if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7)))
pH = (((pH - R.pH) / total_volume) * amount) + pH
if(istype(my_atom, /obj/item/reagent_containers/))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()//checks beaker resilience)
//clamp the removal amount to be between current reagent amount
//and zero, to prevent removing more than the holder has stored
amount = CLAMP(amount, 0, R.volume)
@@ -189,10 +189,16 @@
data["beakerCurrentVolume"] = beakerCurrentVolume
data["beakerMaxVolume"] = beaker.volume
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
data["beakerCurrentpH"] = beaker.reagents.pH
//pH accuracy
for(var/obj/item/stock_parts/capacitor/C in component_parts)
data["partRating"]= 10**(C.rating-1)
else
data["beakerCurrentVolume"] = null
data["beakerMaxVolume"] = null
data["beakerTransferAmounts"] = null
data["beakerCurrentpH"] = null
var/chemicals[0]
var/recipes[0]
@@ -97,13 +97,21 @@
data["isBeakerLoaded"] = beaker ? 1 : 0
data["currentTemp"] = beaker ? beaker.reagents.chem_temp : null
data["currentpH"] = beaker ? beaker.reagents.pH : null
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
data["beakerMaxVolume"] = beaker ? beaker.volume : null
//purity and pH accuracy
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
data["partRating"]= 10**(M.rating-1)
if(M.rating == 4)
data["showPurity"] = 1
else
data["showPurity"] = 0
var beakerContents[0]
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume, "purity" = R.purity))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
return data
@@ -21,6 +21,7 @@
var/analyzeVars[0]
var/useramount = 30 // Last used amount
var/list/pillStyles
var/fermianalyze //Give more detail on fermireactions on analysis
/obj/machinery/chem_master/Initialize()
create_reagents(100)
@@ -170,6 +171,7 @@
data["condi"] = condi
data["screen"] = screen
data["analyzeVars"] = analyzeVars
data["fermianalyze"] = fermianalyze
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
@@ -211,11 +213,13 @@
var/id = params["id"]
var/amount = text2num(params["amount"])
if (amount > 0)
end_fermi_reaction()
beaker.reagents.trans_id_to(src, id, amount)
. = TRUE
else if (amount == -1) // -1 means custom amount
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
if (useramount > 0)
end_fermi_reaction()
beaker.reagents.trans_id_to(src, id, useramount)
. = TRUE
@@ -387,7 +391,14 @@
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
if(istype(R, /datum/reagent/fermi))
fermianalyze = TRUE
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id)
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = initial(R.purity), "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return
@@ -397,6 +408,9 @@
/obj/machinery/chem_master/proc/end_fermi_reaction()//Ends any reactions upon moving.
if(beaker.reagents.fermiIsReacting)
beaker.reagents.fermiEnd()
/obj/machinery/chem_master/proc/isgoodnumber(num)
if(isnum(num))
+12 -1
View File
@@ -33,6 +33,16 @@
var/addiction_stage4_end = 40
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
var/self_consuming = FALSE
//Fermichem vars:
var/purity = 1 //How pure a chemical is from 0 - 1.
var/addProc = FALSE //If the chemical should force an on_new() call
var/turf/loc = null //Should be the creation location!
var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder.
var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction
var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it.
var/DoNotSplit = FALSE // If impurity is handled within the main chem itself
var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging.
var/metabolizing = FALSE
var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
@@ -59,7 +69,8 @@
/datum/reagent/proc/on_mob_life(mob/living/carbon/M)
current_cycle++
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
if(holder)
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
// Called when this reagent is first added to a mob
@@ -14,6 +14,7 @@
nutriment_factor = 0
taste_description = "alcohol"
var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning
pH = 7.33
/*
Boozepwr Chart
@@ -86,6 +87,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "piss water"
glass_name = "glass of beer"
glass_desc = "A freezing pint of beer."
pH = 4
/datum/reagent/consumable/ethanol/beer/light
name = "Light Beer"
@@ -95,6 +98,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "dish water"
glass_name = "glass of light beer"
glass_desc = "A freezing pint of watery light beer."
pH = 5
/datum/reagent/consumable/ethanol/beer/green
name = "Green Beer"
@@ -105,6 +109,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "greenbeerglass"
glass_name = "glass of green beer"
glass_desc = "A freezing pint of green beer. Festive."
pH = 6
/datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/M)
if(M.color != color)
@@ -124,6 +129,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of RR coffee liquor"
glass_desc = "DAMN, THIS THING LOOKS ROBUST!"
shot_glass_icon_state = "shotglasscream"
pH = 6
/datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -145,6 +152,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of whiskey"
glass_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy."
shot_glass_icon_state = "shotglassbrown"
pH = 4.5
/datum/reagent/consumable/ethanol/thirteenloko
name = "Thirteen Loko"
@@ -161,6 +169,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of Thirteen Loko"
glass_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass."
/datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-40)
@@ -221,6 +230,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of vodka"
glass_desc = "The glass contain wodka. Xynta."
shot_glass_icon_state = "shotglassclear"
pH = 8.1
/datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M)
M.radiation = max(M.radiation-2,0)
@@ -255,6 +265,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "threemileislandglass"
glass_name = "Three Mile Island Ice Tea"
glass_desc = "A glass of this is sure to prevent a meltdown."
pH = 3.5
/datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
@@ -270,6 +281,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "ginvodkaglass"
glass_name = "glass of gin"
glass_desc = "A crystal clear glass of Griffeater gin."
pH = 6.9
/datum/reagent/consumable/ethanol/rum
name = "Rum"
@@ -282,6 +294,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of rum"
glass_desc = "Now you want to Pray for a pirate suit, don't you?"
shot_glass_icon_state = "shotglassbrown"
pH = 6.5
/datum/reagent/consumable/ethanol/tequila
name = "Tequila"
@@ -294,6 +307,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of tequila"
glass_desc = "Now all that's missing is the weird colored shades!"
shot_glass_icon_state = "shotglassgold"
pH = 4
/datum/reagent/consumable/ethanol/vermouth
name = "Vermouth"
@@ -306,6 +320,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of vermouth"
glass_desc = "You wonder why you're even drinking this straight."
shot_glass_icon_state = "shotglassclear"
pH = 3.25
/datum/reagent/consumable/ethanol/wine
name = "Wine"
@@ -318,6 +333,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of wine"
glass_desc = "A very classy looking drink."
shot_glass_icon_state = "shotglassred"
pH = 3.45
/datum/reagent/consumable/ethanol/lizardwine
name = "Lizard wine"
@@ -327,6 +343,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 45
quality = DRINK_FANTASTIC
taste_description = "scaley sweetness"
pH = 3
/datum/reagent/consumable/ethanol/grappa
name = "Grappa"
@@ -338,6 +355,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "grappa"
glass_name = "glass of grappa"
glass_desc = "A fine drink originally made to prevent waste by using the leftovers from winemaking."
pH = 3.5
/datum/reagent/consumable/ethanol/cognac
name = "Cognac"
@@ -350,6 +368,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of cognac"
glass_desc = "Damn, you feel like some kind of French aristocrat just by holding this."
shot_glass_icon_state = "shotglassbrown"
pH = 3.5
/datum/reagent/consumable/ethanol/absinthe
name = "Absinthe"
@@ -395,6 +414,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "aleglass"
glass_name = "glass of ale"
glass_desc = "A freezing pint of delicious Ale."
pH = 4.5
/datum/reagent/consumable/ethanol/goldschlager
name = "Goldschlager"
@@ -421,6 +441,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of patron"
glass_desc = "Drinking patron in the bar, with all the subpar ladies."
shot_glass_icon_state = "shotglassclear"
pH = 4.5
/datum/reagent/consumable/ethanol/gintonic
name = "Gin and Tonic"
@@ -433,6 +454,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "gintonicglass"
glass_name = "Gin and Tonic"
glass_desc = "A mild but still great cocktail. Drink up, like a true Englishman."
pH = 3
/datum/reagent/consumable/ethanol/rum_coke
name = "Rum and Coke"
@@ -445,6 +467,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "whiskeycolaglass"
glass_name = "Rum and Coke"
glass_desc = "The classic go-to of space-fratboys."
pH = 4
/datum/reagent/consumable/ethanol/cuba_libre
name = "Cuba Libre"
@@ -458,6 +481,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Cuba Libre"
glass_desc = "A classic mix of rum, cola, and lime. A favorite of revolutionaries everywhere!"
/datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries.
M.adjustBruteLoss(-1, 0)
@@ -504,6 +528,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Vodka martini"
glass_desc ="A bastardisation of the classic martini. Still great."
/datum/reagent/consumable/ethanol/white_russian
name = "White Russian"
id = "whiterussian"
@@ -557,8 +582,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder."
/datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
C.blood_volume = min(BLOOD_VOLUME_NORMAL, C.blood_volume + 3) //Bloody Mary quickly restores blood loss.
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
C.blood_volume = min((BLOOD_VOLUME_NORMAL*C.blood_ratio), C.blood_volume + 3) //Bloody Mary quickly restores blood loss.
..()
/datum/reagent/consumable/ethanol/brave_bull
@@ -643,6 +668,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "beepskysmashglass"
glass_name = "Beepsky Smash"
glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
pH = 2
overdose_threshold = 40
var/datum/brain_trauma/special/beepsky/B
@@ -1578,6 +1604,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Bastion Bourbon"
glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon."
shot_glass_icon_state = "shotglassgreen"
pH = 4
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L)
var/heal_points = 10
@@ -2106,6 +2133,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
can_synth = FALSE
var/list/names = list("null fruit" = 1) //Names of the fruits used. Associative list where name is key, value is the percentage of that fruit.
var/list/tastes = list("bad coding" = 1) //List of tastes. See above.
pH = 4
/datum/reagent/consumable/ethanol/fruit_wine/on_new(list/data)
names = data["names"]
@@ -168,6 +168,7 @@
/datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/M)
M.emote("laugh")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "chemical_laughter", /datum/mood_event/chemical_laughter)
..()
/datum/reagent/consumable/superlaughter
@@ -182,6 +183,7 @@
if(prob(30))
M.visible_message("<span class='danger'>[M] bursts out into a fit of uncontrollable laughter!</span>", "<span class='userdanger'>You burst out in a fit of uncontrollable laughter!</span>")
M.Stun(5)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "chemical_laughter", /datum/mood_event/chemical_superlaughter)
..()
/datum/reagent/consumable/potato_juice
@@ -15,6 +15,7 @@
description = "An illegal chemical compound used as drug."
color = "#60A584" // rgb: 96, 165, 132
overdose_threshold = 30
pH = 9
/datum/reagent/drug/space_drugs/on_mob_life(mob/living/carbon/M)
M.set_drugginess(15)
@@ -44,6 +45,7 @@
addiction_threshold = 30
taste_description = "smoke"
trippy = FALSE
pH = 8
/datum/reagent/drug/nicotine/on_mob_life(mob/living/carbon/M)
if(prob(1))
@@ -65,6 +67,7 @@
color = "#FA00C8"
overdose_threshold = 20
addiction_threshold = 10
pH = 10
/datum/reagent/drug/crank/on_mob_life(mob/living/carbon/M)
if(prob(5))
@@ -112,6 +115,7 @@
color = "#0064B4"
overdose_threshold = 20
addiction_threshold = 15
pH = 9
/datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/M)
@@ -167,6 +171,7 @@
var/brain_damage = TRUE
var/jitter = TRUE
var/confusion = TRUE
pH = 5
/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L)
..()
@@ -261,6 +266,7 @@
addiction_threshold = 10
taste_description = "salt" // because they're bathsalts?
var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage
pH = 8.2
/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L)
..()
@@ -357,6 +363,7 @@
description = "Amps you up and gets you going, fixes all stamina damage you might have but can cause toxin and oxygen damage."
reagent_state = LIQUID
color = "#78FFF0"
pH = 9.2
/datum/reagent/drug/aranesp/on_mob_life(mob/living/carbon/M)
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
@@ -370,6 +377,84 @@
..()
. = 1
/datum/reagent/drug/happiness
name = "Happiness"
id = "happiness"
description = "Fills you with ecstasic numbness and causes minor brain damage. Highly addictive. If overdosed causes sudden mood swings."
reagent_state = LIQUID
color = "#FFF378"
addiction_threshold = 10
overdose_threshold = 20
pH = 10.5
/datum/reagent/drug/happiness/on_mob_add(mob/living/L)
..()
ADD_TRAIT(L, TRAIT_FEARLESS, id)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug)
/datum/reagent/drug/happiness/on_mob_delete(mob/living/L)
REMOVE_TRAIT(L, TRAIT_FEARLESS, id)
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "happiness_drug")
..()
/datum/reagent/drug/happiness/on_mob_life(mob/living/carbon/M)
M.jitteriness = 0
M.confused = 0
M.disgust = 0
M.adjustBrainLoss(0.2)
..()
. = 1
/datum/reagent/drug/happiness/overdose_process(mob/living/M)
if(prob(30))
var/reaction = rand(1,3)
switch(reaction)
if(1)
M.emote("laugh")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_good_od)
if(2)
M.emote("sway")
M.Dizzy(25)
if(3)
M.emote("frown")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_bad_od)
M.adjustBrainLoss(0.5)
..()
. = 1
/datum/reagent/drug/happiness/addiction_act_stage1(mob/living/M)// all work and no play makes jack a dull boy
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
mood.setSanity(min(mood.sanity, SANITY_DISTURBED))
M.Jitter(5)
if(prob(20))
M.emote(pick("twitch","laugh","frown"))
..()
/datum/reagent/drug/happiness/addiction_act_stage2(mob/living/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
mood.setSanity(min(mood.sanity, SANITY_UNSTABLE))
M.Jitter(10)
if(prob(30))
M.emote(pick("twitch","laugh","frown"))
..()
/datum/reagent/drug/happiness/addiction_act_stage3(mob/living/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
mood.setSanity(min(mood.sanity, SANITY_CRAZY))
M.Jitter(15)
if(prob(40))
M.emote(pick("twitch","laugh","frown"))
..()
/datum/reagent/drug/happiness/addiction_act_stage4(mob/living/carbon/human/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
mood.setSanity(SANITY_INSANE)
M.Jitter(20)
if(prob(50))
M.emote(pick("twitch","laugh","frown"))
..()
. = 1
/datum/reagent/drug/skooma
name = "Skooma"
id = "skooma"
@@ -380,6 +465,7 @@
addiction_threshold = 1
addiction_stage3_end = 40
addiction_stage4_end = 240
pH = 12.5
/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L)
. = ..()
@@ -440,4 +526,3 @@
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
@@ -230,6 +230,7 @@
description = "A special oil that noticably chills the body. Extracted from Icepeppers and slimes."
color = "#8BA6E9" // rgb: 139, 166, 233
taste_description = "mint"
pH = 13 //HMM! I wonder
/datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/M)
var/cooling = 0
@@ -275,6 +276,7 @@
description = "A chemical agent used for self-defense and in police work."
color = "#B31008" // rgb: 179, 16, 8
taste_description = "scorching agony"
pH = 7.4
/datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(!ishuman(M) && !ismonkey(M))
@@ -402,6 +404,7 @@
color = "#E700E7" // rgb: 231, 0, 231
metabolization_rate = 0.2 * REAGENTS_METABOLISM
taste_description = "mushroom"
pH = 11
/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M)
M.slurring = max(M.slurring,50)
@@ -618,6 +621,7 @@
description = "A blinding substance extracted from certain onions."
color = "#c0c9a0"
taste_description = "bitterness"
pH = 5
/datum/reagent/consumable/tearjuice/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(!istype(M))
@@ -672,6 +676,7 @@
description = "An ichor, derived from a certain mushroom, makes for a bad time."
color = "#1d043d"
taste_description = "bitter mushroom"
pH = 12
/datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/M)
if(current_cycle >= 10)
@@ -692,6 +697,7 @@
description = "A stimulating ichor which causes luminescent fungi to grow on the skin. "
color = "#b5a213"
taste_description = "tingling mushroom"
pH = 11.2
/datum/reagent/consumable/tinlux/reaction_mob(mob/living/M)
M.set_light(2)
@@ -706,6 +712,7 @@
color = "#d3a308"
nutriment_factor = 3 * REAGENTS_METABOLISM
taste_description = "fruity mushroom"
pH = 10.4
/datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M)
if(prob(80))
@@ -721,6 +728,7 @@
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#eef442" // rgb: 238, 244, 66
taste_description = "mournful honking"
pH = 9.2
/datum/reagent/consumable/astrotame
name = "Astrotame"
@@ -750,3 +758,4 @@
quality = FOOD_AMAZING
taste_mult = 100
can_synth = FALSE
pH = 6.1
@@ -18,6 +18,7 @@
name = "Leporazine"
id = "leporazine"
description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels."
pH = 8.4
color = "#82b8aa"
/datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/M)
@@ -60,6 +61,9 @@
M.SetSleeping(0, 0)
M.jitteriness = 0
M.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume = (BLOOD_VOLUME_NORMAL*M.blood_ratio)
for(var/thing in M.diseases)
var/datum/disease/D = thing
if(D.severity == DISEASE_SEVERITY_POSITIVE)
@@ -79,6 +83,7 @@
id = "synaptizine"
description = "Increases resistance to stuns as well as reducing drowsiness and hallucinations."
color = "#FF00FF"
pH = 4
/datum/reagent/medicine/synaptizine/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(M.drowsyness-5, 0)
@@ -98,6 +103,7 @@
id = "synaphydramine"
description = "Reduces drowsiness, hallucinations, and Histamine from body."
color = "#EC536D" // rgb: 236, 83, 109
pH = 5.2
/datum/reagent/medicine/synaphydramine/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(M.drowsyness-5, 0)
@@ -116,6 +122,7 @@
id = "inacusiate"
description = "Instantly restores all hearing to the patient, but does not cure deafness."
color = "#6600FF" // rgb: 100, 165, 255
pH = 2
/datum/reagent/medicine/inacusiate/on_mob_life(mob/living/carbon/M)
M.restoreEars()
@@ -127,6 +134,7 @@
description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 270K for it to metabolise correctly."
color = "#0000C8"
taste_description = "sludge"
pH = 11
/datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/carbon/M)
var/power = -0.00003 * (M.bodytemperature ** 2) + 3
@@ -148,6 +156,7 @@
color = "#0000C8"
taste_description = "muscle"
metabolization_rate = 1.5 * REAGENTS_METABOLISM
pH = 13
/datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M)
if(M.bodytemperature < T0C)
@@ -163,6 +172,7 @@
description = "A mixture of cryoxadone and slime jelly, that apparently inverses the requirement for its activation."
color = "#f7832a"
taste_description = "spicy jelly"
pH = 12
/datum/reagent/medicine/pyroxadone/on_mob_life(mob/living/carbon/M)
if(M.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
@@ -194,6 +204,7 @@
color = "#669900" // rgb: 102, 153, 0
overdose_threshold = 30
taste_description = "fish"
pH = 12.2
/datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/M)
M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that.
@@ -215,6 +226,7 @@
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with."
color = "#f2f2f2"
metabolization_rate = 0.1 * REAGENTS_METABOLISM
pH = 8.1
//Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects.
/datum/reagent/medicine/silver_sulfadiazine
@@ -222,6 +234,7 @@
id = "silver_sulfadiazine"
description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage."
reagent_state = LIQUID
pH = 7.2
color = "#ffeac9"
/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
@@ -235,6 +248,7 @@
if(show_message)
to_chat(M, "<span class='danger'>You feel your burns healing! It stings like hell!</span>")
M.emote("scream")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
..()
/datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/carbon/M)
@@ -250,6 +264,7 @@
color = "#f7ffa5"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 25
pH = 10.7
/datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M)
if(M.getFireLoss() > 50)
@@ -271,6 +286,7 @@
description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. If ingested through other means, deals minor toxin damage."
reagent_state = LIQUID
color = "#FF9696"
pH = 6.7
/datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -283,6 +299,7 @@
if(show_message)
to_chat(M, "<span class='danger'>You feel your bruises healing! It stings like hell!</span>")
M.emote("scream")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
..()
@@ -302,6 +319,7 @@
taste_description = "sweetness and salt"
var/last_added = 0
var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active
pH = 5.5
/datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M)
if(last_added)
@@ -340,6 +358,7 @@
reagent_state = LIQUID
color = "#6D6374"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
pH = 2.6
/datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C)
C.hal_screwyhud = SCREWYHUD_HEALTHY
@@ -378,6 +397,7 @@
description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only."
reagent_state = LIQUID
color = "#FFEBEB"
pH = 11.5
/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1)
if(iscarbon(M))
@@ -388,6 +408,7 @@
M.adjustFireLoss(-1.25 * reac_volume)
if(show_message)
to_chat(M, "<span class='danger'>You feel your burns and bruises healing! It stings like hell!</span>")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
..()
/datum/reagent/medicine/charcoal
@@ -398,6 +419,7 @@
color = "#000000"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "ash"
pH = 5
/datum/reagent/medicine/charcoal/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(-2*REM, 0)
@@ -415,6 +437,7 @@
color = "#DCDCDC"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 30
pH = 2
/datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(-0.5*REM, 0)
@@ -440,6 +463,7 @@
color = "#19C832"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "acid"
pH = 1.5
/datum/reagent/medicine/calomel/on_mob_life(mob/living/carbon/M)
for(var/datum/reagent/R in M.reagents.reagent_list)
@@ -457,6 +481,7 @@
reagent_state = LIQUID
color = "#14FF3C"
metabolization_rate = 2 * REAGENTS_METABOLISM
pH = 12 //It's a reducing agent
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/M)
if(M.radiation > 0)
@@ -470,6 +495,7 @@
reagent_state = LIQUID
color = "#003153" // RGB 0, 49, 83
metabolization_rate = 0.5 * REAGENTS_METABOLISM
pH = 8.9
/datum/reagent/medicine/prussian_blue/on_mob_life(mob/living/carbon/M)
if(M.radiation > 0)
@@ -483,6 +509,7 @@
reagent_state = LIQUID
color = "#E6FFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
pH = 1 //One of the best buffers, NEVERMIND!
var/healtoxinlover = FALSE
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M)
@@ -500,6 +527,7 @@
description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!"
color = "#91D865"
healtoxinlover = TRUE
pH = 12//invert
/datum/reagent/medicine/sal_acid
name = "Salicyclic Acid"
@@ -509,6 +537,7 @@
color = "#D2D2D2"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 25
pH = 2.1
/datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M)
@@ -532,6 +561,7 @@
reagent_state = LIQUID
color = "#00FFFF"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
pH = 2
/datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M)
M.adjustOxyLoss(-3*REM, 0)
@@ -547,6 +577,7 @@
reagent_state = LIQUID
color = "#FF6464"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
pH = 11
/datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M)
M.adjustOxyLoss(-12*REM, 0)
@@ -566,6 +597,7 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 45
addiction_threshold = 30
pH = 12
/datum/reagent/medicine/ephedrine/on_mob_life(mob/living/carbon/M)
M.AdjustStun(-20, 0)
@@ -620,6 +652,7 @@
reagent_state = LIQUID
color = "#64FFE6"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
pH = 11.5
/datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/carbon/M)
if(prob(10))
@@ -637,6 +670,7 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 30
addiction_threshold = 25
pH = 8.96
/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L)
..()
@@ -705,6 +739,7 @@
color = "#FFFFFF"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
taste_description = "dull toxin"
pH = 10
/datum/reagent/medicine/oculine/on_mob_life(mob/living/carbon/M)
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
@@ -736,6 +771,7 @@
color = "#000000"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 35
pH = 12
/datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/M)
if(M.health < 0)
@@ -765,6 +801,7 @@
color = "#D2FFFA"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 30
pH = 10.2
/datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/M)
if(M.health < 0)
@@ -801,6 +838,7 @@
color = "#A0E85E"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "magnets"
pH = 0
/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume)
if(M.stat == DEAD)
@@ -834,6 +872,7 @@
id = "mannitol"
description = "Efficiently restores brain damage."
color = "#DCDCFF"
pH = 10.4
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C)
C.adjustBrainLoss(-2*REM)
@@ -841,12 +880,26 @@
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
..()
/datum/reagent/medicine/neurine
name = "Neurine"
id = "neurine"
description = "Reacts with neural tissue, helping reform damaged connections. Can cure minor traumas."
color = "#EEFF8F"
/datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C)
if(holder.has_reagent("neurotoxin"))
holder.remove_reagent("neurotoxin", 5)
if(prob(15))
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
..()
/datum/reagent/medicine/mutadone
name = "Mutadone"
id = "mutadone"
description = "Removes jitteriness and restores genetic defects."
color = "#5096C8"
taste_description = "acid"
pH = 2
/datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/M)
M.jitteriness = 0
@@ -861,6 +914,7 @@
description = "Purges alcoholic substance from the patient's body and eliminates its side effects."
color = "#00B4C8"
taste_description = "raw egg"
pH = 4
/datum/reagent/medicine/antihol/on_mob_life(mob/living/carbon/M)
M.dizziness = 0
@@ -882,6 +936,7 @@
color = "#78008C"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 60
pH = 8.7
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L)
..()
@@ -919,6 +974,7 @@
reagent_state = LIQUID
color = "#FFFFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
pH = 6.7
/datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/M)
if(M.AdjustSleeping(-20, FALSE))
@@ -934,6 +990,7 @@
reagent_state = LIQUID
color = "#fc2626"
overdose_threshold = 30
pH = 5
/datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-2*REM, 0)
@@ -952,6 +1009,7 @@
reagent_state = LIQUID
color = "#13d2f0"
overdose_threshold = 30
pH = 9.7
/datum/reagent/medicine/dexalin/on_mob_life(mob/living/carbon/M)
M.adjustOxyLoss(-2*REM, 0)
@@ -970,6 +1028,7 @@
reagent_state = LIQUID
color = "#ffc400"
overdose_threshold = 30
pH = 9
/datum/reagent/medicine/kelotane/on_mob_life(mob/living/carbon/M)
M.adjustFireLoss(-2*REM, 0)
@@ -989,6 +1048,7 @@
color = "#6aff00"
overdose_threshold = 30
taste_description = "a roll of gauze"
pH = 10
/datum/reagent/medicine/antitoxin/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(-2*REM, 0)
@@ -1007,6 +1067,7 @@
id = "inaprovaline"
description = "Stabilizes the breathing of patients. Good for those in critical condition."
reagent_state = LIQUID
pH = 8.5
color = "#5dc1f0"
/datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M)
@@ -1062,6 +1123,7 @@
description = "Miniature medical robots that swiftly restore bodily damage."
reagent_state = SOLID
color = "#555555"
pH = 11
/datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-5*REM, 0) //A ton of healing - this is a 50 telecrystal investment.
@@ -1075,14 +1137,15 @@
. = 1
/datum/reagent/medicine/neo_jelly
name = "Neo Jelly"
id = "neo_jelly"
description = "Gradually regenerates all types of damage, without harming slime anatomy.Can OD"
reagent_state = LIQUID
metabolization_rate = 1 * REAGENTS_METABOLISM
color = "#91D865"
overdose_threshold = 30
taste_description = "jelly"
name = "Neo Jelly"
id = "neo_jelly"
description = "Gradually regenerates all types of damage, without harming slime anatomy.Can OD"
reagent_state = LIQUID
metabolization_rate = 1 * REAGENTS_METABOLISM
color = "#91D865"
overdose_threshold = 30
taste_description = "jelly"
pH = 11.8
/datum/reagent/medicine/neo_jelly/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-1.5*REM, 0)
@@ -1105,6 +1168,7 @@
description = "Ichor from an extremely powerful plant. Great for restoring wounds, but it's a little heavy on the brain."
color = rgb(255, 175, 0)
overdose_threshold = 25
pH = 11
/datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-3 * REM, 0)
@@ -1132,6 +1196,7 @@
reagent_state = LIQUID
color = "#27870a"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
pH = 4.3
/datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/M)
for(var/datum/reagent/drug/R in M.reagents.reagent_list)
@@ -1154,6 +1219,7 @@
color = "#a1a1a1"
overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent
can_synth = FALSE
pH = 14
/datum/reagent/medicine/lavaland_extract/on_mob_life(mob/living/carbon/M)
M.heal_bodypart_damage(5,5)
@@ -1217,6 +1283,7 @@
description = "A medication used to treat pain, fever, and inflammation, along with heart attacks."
color = "#F5F5F5"
self_consuming = TRUE
pH = 12.5
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
..()
@@ -1249,6 +1316,7 @@
overdose_threshold = 20 // with the random effects this might be awesome or might kill you at less than 10u (extensively tested)
taste_description = "salt" // it actually does taste salty
var/overdose_progress = 0 // to track overdose progress
pH = 7.89
/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M)
ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id)
@@ -1305,3 +1373,38 @@
M.adjustStaminaLoss(1.5*REM, 0)
..()
return TRUE
/datum/reagent/medicine/psicodine
name = "Psicodine"
id = "psicodine"
description = "Suppresses anxiety and other various forms of mental distress. Overdose causes hallucinations and minor toxin damage."
reagent_state = LIQUID
color = "#07E79E"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 30
pH = 9.12
/datum/reagent/medicine/psicodine/on_mob_add(mob/living/L)
..()
ADD_TRAIT(L, TRAIT_FEARLESS, id)
/datum/reagent/medicine/psicodine/on_mob_delete(mob/living/L)
REMOVE_TRAIT(L, TRAIT_FEARLESS, id)
..()
/datum/reagent/medicine/psicodine/on_mob_life(mob/living/carbon/M)
M.jitteriness = max(0, M.jitteriness-6)
M.dizziness = max(0, M.dizziness-6)
M.confused = max(0, M.confused-6)
M.disgust = max(0, M.disgust-6)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
if(mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then...
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral
..()
. = 1
/datum/reagent/medicine/psicodine/overdose_process(mob/living/M)
M.hallucination = min(max(0, M.hallucination + 5), 60)
M.adjustToxLoss(1, 0)
..()
. = 1
@@ -10,6 +10,7 @@
glass_name = "glass of tomato juice"
glass_desc = "Are you sure this is tomato juice?"
shot_glass_icon_state = "shotglassred"
pH = 7.4
/datum/reagent/blood/reaction_mob(mob/living/L, method=TOUCH, reac_volume)
if(data && data["viruses"])
@@ -95,6 +96,7 @@
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
shot_glass_icon_state = "shotglassred"
pH = 7.45
/datum/reagent/vaccine
//data must contain virus type
@@ -195,6 +197,7 @@
glass_icon_state = "glass_clear"
glass_name = "glass of holy water"
glass_desc = "A glass of holy water."
pH = 7.5 //God is alkaline
/datum/reagent/water/holywater/on_mob_metabolize(mob/living/L)
..()
@@ -271,6 +274,7 @@
id = "unholywater"
description = "Something that shouldn't exist on this plane of existence."
taste_description = "suffering"
pH = 6.5
/datum/reagent/fuel/unholywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
@@ -289,7 +293,7 @@
M.adjustOxyLoss(-2, 0)
M.adjustBruteLoss(-2, 0)
M.adjustFireLoss(-2, 0)
if(ishuman(M) && M.blood_volume < BLOOD_VOLUME_NORMAL)
if(ishuman(M) && M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume += 3
else // Will deal about 90 damage when 50 units are thrown
M.adjustBrainLoss(3, 150)
@@ -313,6 +317,7 @@
M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard?
M.adjustBrainLoss(5, 150)
holder.remove_reagent(id, 1)
pH = 0.1
/datum/reagent/fuel/holyoil //Its oil
name = "Zelus Oil"
@@ -380,6 +385,7 @@
metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose
overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle.
taste_description = "sour oranges"
pH = 5
/datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(ishuman(M))
@@ -704,6 +710,7 @@
color = "#202040" // rgb: 20, 20, 40
metabolization_rate = 0.25 * REAGENTS_METABOLISM
taste_description = "bitterness"
pH = 10
/datum/reagent/serotrotium/on_mob_life(mob/living/carbon/M)
if(ishuman(M))
@@ -718,6 +725,7 @@
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0 // oderless and tasteless
pH = 9.2//It's acutally a huge range and very dependant on the chemistry but pH is basically a made up var in it's implementation anyways
/datum/reagent/oxygen/reaction_obj(obj/O, reac_volume)
if((!O) || (!reac_volume))
@@ -738,6 +746,7 @@
reagent_state = SOLID
color = "#6E3B08" // rgb: 110, 59, 8
taste_description = "metal"
pH = 5.5
/datum/reagent/copper/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/item/stack/sheet/metal))
@@ -754,6 +763,7 @@
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0
/datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume)
if((!O) || (!reac_volume))
return 0
@@ -773,6 +783,7 @@
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0
pH = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve pHes? (not 0 so I don't get div/0 errors)
/datum/reagent/potassium
name = "Potassium"
@@ -804,6 +815,7 @@
reagent_state = SOLID
color = "#BF8C00" // rgb: 191, 140, 0
taste_description = "rotten eggs"
pH = 4.5
/datum/reagent/carbon
name = "Carbon"
@@ -812,6 +824,7 @@
reagent_state = SOLID
color = "#1C1300" // rgb: 30, 20, 0
taste_description = "sour chalk"
pH = 5
/datum/reagent/carbon/reaction_turf(turf/T, reac_volume)
if(!isspaceturf(T))
@@ -826,6 +839,7 @@
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
taste_description = "chlorine"
pH = 7.4
/datum/reagent/chlorine/on_mob_life(mob/living/carbon/M)
M.take_bodypart_damage(1*REM, 0, 0, 0)
@@ -839,6 +853,7 @@
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
taste_description = "acid"
pH = 2
/datum/reagent/fluorine/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(1*REM, 0)
@@ -852,6 +867,7 @@
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
taste_description = "salty metal"
pH = 11.6
/datum/reagent/phosphorus
name = "Phosphorus"
@@ -860,6 +876,7 @@
reagent_state = SOLID
color = "#832828" // rgb: 131, 40, 40
taste_description = "vinegar"
pH = 6.5
/datum/reagent/lithium
name = "Lithium"
@@ -868,6 +885,7 @@
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
taste_description = "metal"
pH = 11.3
/datum/reagent/lithium/on_mob_life(mob/living/carbon/M)
if(M.canmove && !isspaceturf(M.loc))
@@ -882,6 +900,7 @@
description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity."
color = "#808080" // rgb: 128, 128, 128
taste_description = "sweetness"
pH = 9
/datum/reagent/radium
name = "Radium"
@@ -890,6 +909,7 @@
reagent_state = SOLID
color = "#C7C7C7" // rgb: 199,199,199
taste_description = "the colour blue and regret"
pH = 10
/datum/reagent/radium/on_mob_life(mob/living/carbon/M)
M.apply_effect(2*REM/M.metabolism_efficiency,EFFECT_IRRADIATE,0)
@@ -909,6 +929,7 @@
description = "Sterilizes wounds in preparation for surgery."
color = "#e6f1f5" // rgb: 200, 165, 220
taste_description = "bitterness"
pH = 10.5
/datum/reagent/space_cleaner/sterilizine/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume)
if(method in list(TOUCH, VAPOR, PATCH))
@@ -924,11 +945,12 @@
description = "Pure iron is a metal."
reagent_state = SOLID
taste_description = "iron"
pH = 6
color = "#c2391d"
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
C.blood_volume += 0.5
..()
@@ -966,6 +988,7 @@
reagent_state = SOLID
color = "#B8B8C0" // rgb: 184, 184, 192
taste_description = "the inside of a reactor"
pH = 4
/datum/reagent/uranium/on_mob_life(mob/living/carbon/M)
M.apply_effect(1/M.metabolism_efficiency,EFFECT_IRRADIATE,0)
@@ -986,6 +1009,7 @@
reagent_state = SOLID
color = "#0000CC"
taste_description = "fizzling blue"
pH = 12
/datum/reagent/bluespace/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
@@ -1018,6 +1042,7 @@
reagent_state = SOLID
color = "#A8A8A8" // rgb: 168, 168, 168
taste_mult = 0
pH = 10
/datum/reagent/fuel
name = "Welding fuel"
@@ -1028,6 +1053,8 @@
glass_icon_state = "dr_gibb_glass"
glass_name = "glass of welder fuel"
glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption."
pH = 4
/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite!
if(method == TOUCH || method == VAPOR)
@@ -1046,6 +1073,7 @@
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
color = "#A5F0EE" // rgb: 165, 240, 238
taste_description = "sourness"
pH = 5.5
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/effect/decal/cleanable))
@@ -1103,6 +1131,7 @@
description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "acid"
pH = 2
/datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(3.33)
@@ -1123,6 +1152,7 @@
color = "#7529b3" // rgb: 200, 165, 220
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "sourness"
pH = 11.9
/datum/reagent/cryptobiolin/on_mob_life(mob/living/carbon/M)
M.Dizzy(1)
@@ -1137,6 +1167,7 @@
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
color = "#587a31" // rgb: 200, 165, 220A
taste_description = "numbness"
pH = 9.1
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M)
M.jitteriness = max(M.jitteriness-5,0)
@@ -1179,6 +1210,7 @@
color = "#92D17D" // rgb: 146, 209, 125
can_synth = FALSE
taste_description = "slime"
pH = 11
/datum/reagent/fungalspores/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
@@ -1190,6 +1222,7 @@
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
color = "#9E6B38" // rgb: 158, 107, 56
taste_description = "metal"
pH = 13
/datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
name = "Foaming agent"
@@ -1198,6 +1231,7 @@
reagent_state = SOLID
color = "#664B63" // rgb: 102, 75, 99
taste_description = "metal"
pH = 12.5
/datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls.
name = "Smart foaming agent"
@@ -1206,6 +1240,7 @@
reagent_state = SOLID
color = "#664B63" // rgb: 102, 75, 99
taste_description = "metal"
pH = 11.8
/datum/reagent/ammonia
name = "Ammonia"
@@ -1214,6 +1249,7 @@
reagent_state = GAS
color = "#404030" // rgb: 64, 64, 48
taste_description = "mordant"
pH = 11.6
/datum/reagent/diethylamine
name = "Diethylamine"
@@ -1221,6 +1257,7 @@
description = "A secondary amine, mildly corrosive."
color = "#604030" // rgb: 96, 64, 48
taste_description = "iron"
pH = 12
/datum/reagent/carbondioxide
name = "Carbon Dioxide"
@@ -1229,6 +1266,7 @@
description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs."
color = "#B0B0B0" // rgb : 192, 192, 192
taste_description = "something unknowable"
pH = 6
/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume)
if((!O) || (!reac_volume))
@@ -1250,6 +1288,7 @@
metabolization_rate = 1.5 * REAGENTS_METABOLISM
color = "#808080"
taste_description = "sweetness"
pH = 5.8
/datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume)
if((!O) || (!reac_volume))
@@ -1309,6 +1348,7 @@
metabolization_rate = REAGENTS_METABOLISM
color = "90560B"
taste_description = "burning"
pH = 2
/datum/reagent/nitryl/on_mob_metabolize(mob/living/L)
..()
@@ -1342,6 +1382,7 @@
colorname = "red"
color = "#DA0000" // red
random_color_list = list("#DA0000")
pH = 0.5
/datum/reagent/colorful_reagent/crayonpowder/orange
name = "Orange Crayon Powder"
@@ -1349,6 +1390,7 @@
colorname = "orange"
color = "#FF9300" // orange
random_color_list = list("#FF9300")
pH = 2
/datum/reagent/colorful_reagent/crayonpowder/yellow
name = "Yellow Crayon Powder"
@@ -1356,6 +1398,7 @@
colorname = "yellow"
color = "#FFF200" // yellow
random_color_list = list("#FFF200")
pH = 5
/datum/reagent/colorful_reagent/crayonpowder/green
name = "Green Crayon Powder"
@@ -1364,12 +1407,14 @@
color = "#A8E61D" // green
random_color_list = list("#A8E61D")
/datum/reagent/colorful_reagent/crayonpowder/blue
name = "Blue Crayon Powder"
id = "bluecrayonpowder"
colorname = "blue"
color = "#00B7EF" // blue
random_color_list = list("#00B7EF")
pH = 10
/datum/reagent/colorful_reagent/crayonpowder/purple
name = "Purple Crayon Powder"
@@ -1377,6 +1422,7 @@
colorname = "purple"
color = "#DA00FF" // purple
random_color_list = list("#DA00FF")
pH = 13
/datum/reagent/colorful_reagent/crayonpowder/invisible
name = "Invisible Crayon Powder"
@@ -1411,6 +1457,7 @@
color = "#000000" // RBG: 0, 0, 0
var/tox_prob = 0
taste_description = "plant food"
pH = 3
/datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/M)
if(prob(tox_prob))
@@ -1424,6 +1471,7 @@
description = "Cheap and extremely common type of plant nutriment."
color = "#376400" // RBG: 50, 100, 0
tox_prob = 10
pH = 2
/datum/reagent/plantnutriment/left4zednutriment
name = "Left 4 Zed"
@@ -1431,6 +1479,7 @@
description = "Unstable nutriment that makes plants mutate more often than usual."
color = "#1A1E4D" // RBG: 26, 30, 77
tox_prob = 25
pH = 1.5
/datum/reagent/plantnutriment/robustharvestnutriment
name = "Robust Harvest"
@@ -1438,6 +1487,7 @@
description = "Very potent nutriment that prevents plants from mutating."
color = "#9D9D00" // RBG: 157, 157, 0
tox_prob = 15
pH = 1
@@ -1465,6 +1515,7 @@
color = "#6b008f"
taste_description = "bitterness"
taste_mult = 1.5
pH = 1.5
/datum/reagent/stable_plasma/on_mob_life(mob/living/carbon/C)
C.adjustPlasma(10)
@@ -1477,6 +1528,7 @@
reagent_state = LIQUID
color = "#694600"
taste_description = "metal"
pH = 4.5
/datum/reagent/carpet
name = "Carpet"
@@ -1499,14 +1551,16 @@
reagent_state = LIQUID
color = "#b37740"
taste_description = "chemicals"
pH = 7.8
/datum/reagent/phenol
name = "Phenol"
id = "phenol"
description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own."
reagent_state = LIQUID
taste_description = "sweet and tarry" //Again, not a strong acid.
pH = 5.5
color = "#e6e8ff"
taste_description = "acid"
/datum/reagent/ash
name = "Ash"
@@ -1515,14 +1569,15 @@
reagent_state = LIQUID
color = "#665c56"
taste_description = "ash"
pH = 6.5
/datum/reagent/acetone
name = "Acetone"
id = "acetone"
description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life."
reagent_state = LIQUID
taste_description = "solvent"//It's neutral though..?
color = "#e6e6e6"
taste_description = "acid"
/datum/reagent/colorful_reagent
name = "Colorful Reagent"
@@ -1612,6 +1667,7 @@
reagent_state = LIQUID
color = "#60A584" // rgb: 96, 165, 132
taste_description = "cool salt"
pH = 11.2
/datum/reagent/lye
name = "Lye"
@@ -1619,7 +1675,8 @@
description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming."
reagent_state = LIQUID
color = "#FFFFD6" // very very light yellow
taste_description = "acid"
taste_description = "alkali" //who put ACID for NaOH ????
pH = 13
/datum/reagent/drying_agent
name = "Drying agent"
@@ -1628,6 +1685,7 @@
reagent_state = LIQUID
color = "#A70FFF"
taste_description = "dryness"
pH = 10.7
/datum/reagent/drying_agent/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
@@ -1699,6 +1757,7 @@
description = "Royal Bee Jelly, if injected into a Queen Space Bee said bee will split into two bees."
color = "#00ff80"
taste_description = "strange honey"
pH = 3
/datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/M)
if(prob(2))
@@ -1720,6 +1779,7 @@
metabolization_rate = INFINITY
can_synth = FALSE
taste_description = "brains"
pH = 0.5
/datum/reagent/romerol/reaction_mob(mob/living/carbon/human/H, method=TOUCH, reac_volume)
// Silently add the zombie infection organ to be activated upon death
@@ -1778,6 +1838,7 @@
description = "the petroleum based components of plastic."
color = "#f7eded"
taste_description = "plastic"
pH = 6
/datum/reagent/glitter
name = "generic glitter"
@@ -1820,6 +1881,7 @@
color = "#AAAAAA55"
taste_description = "water"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
pH = 15
/datum/reagent/pax/on_mob_metabolize(mob/living/L)
..()
@@ -1908,6 +1970,13 @@
color = "#FAEAFF"
taste_description = "synthetic catnip"
/datum/reagent/moonsugar/on_mob_life(mob/living/carbon/M)
if(prob(20))
to_chat(M, "You find yourself unable to supress the desire to meow!")
M.emote("nya")
..()
//Kept for legacy, I think it will break everything if you enable it.
/datum/reagent/penis_enlargement
name = "Penis Enlargement"
id = "penis_enlargement"
@@ -23,6 +23,7 @@
color = "#792300" // rgb: 121, 35, 0
toxpwr = 2.5
taste_description = "mushroom"
pH = 13
/datum/reagent/toxin/mutagen
name = "Unstable mutagen"
@@ -32,6 +33,7 @@
toxpwr = 0
taste_description = "slime"
taste_mult = 0.9
pH = 2
/datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume)
if(!..())
@@ -61,6 +63,7 @@
taste_mult = 1.5
color = "#8228A0"
toxpwr = 3
pH = 4
/datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C)
if(holder.has_reagent("epinephrine"))
@@ -93,6 +96,7 @@
color = "#7DC3A0"
toxpwr = 0
taste_description = "acid"
pH = 1.2
/datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/C)
. = TRUE
@@ -115,6 +119,7 @@
toxpwr = 0
taste_description = "slime"
taste_mult = 1.3
pH = 10
/datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/M)
if(prob(10))
@@ -133,6 +138,7 @@
color = "#CF3600" // rgb: 207, 54, 0
toxpwr = 0
taste_description = "mint"
pH = 8
/datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M)
if(HAS_TRAIT(M, TRAIT_FAT))
@@ -146,6 +152,7 @@
color = "#003333" // rgb: 0, 51, 51
toxpwr = 2
taste_description = "fish"
pH = 12
/datum/reagent/toxin/zombiepowder
name = "Zombie Powder"
@@ -155,6 +162,7 @@
color = "#669900" // rgb: 102, 153, 0
toxpwr = 0.5
taste_description = "death"
pH = 13
/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L)
..()
@@ -177,6 +185,7 @@
color = "#664700" // rgb: 102, 71, 0
toxpwr = 0.8
taste_description = "death"
pH = 14.5
/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L)
..()
@@ -198,6 +207,7 @@
color = "#B31008" // rgb: 139, 166, 233
toxpwr = 0
taste_description = "sourness"
pH = 11
/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/M)
M.hallucination += 5
@@ -210,6 +220,7 @@
color = "#49002E" // rgb: 73, 0, 46
toxpwr = 1
taste_mult = 1
pH = 2
/datum/reagent/toxin/plantbgone/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/structure/alien/weeds))
@@ -234,6 +245,7 @@
id = "weedkiller"
description = "A harmful toxic mixture to kill weeds. Do not ingest!"
color = "#4B004B" // rgb: 75, 0, 75
pH = 3
/datum/reagent/toxin/pestkiller
name = "Pest Killer"
@@ -241,6 +253,7 @@
description = "A harmful toxic mixture to kill pests. Do not ingest!"
color = "#4B004B" // rgb: 75, 0, 75
toxpwr = 1
pH = 3.2
/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
..()
@@ -254,6 +267,7 @@
description = "A natural toxin produced by blob spores that inhibits vision when ingested."
color = "#9ACD32"
toxpwr = 1
pH = 11
/datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/C)
C.damageoverlaytemp = 60
@@ -268,6 +282,7 @@
color = "#9ACD32"
toxpwr = 0.5
taste_description = "burning"
pH = 13
/datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/M)
M.adjust_fire_stacks(2)
@@ -282,6 +297,7 @@
color = "#000067" // rgb: 0, 0, 103
toxpwr = 0
metabolization_rate = 1.5 * REAGENTS_METABOLISM
pH = 11
/datum/reagent/toxin/chloralhydrate/on_mob_life(mob/living/carbon/M)
switch(current_cycle)
@@ -326,6 +342,7 @@
glass_icon_state = "beerglass"
glass_name = "glass of beer"
glass_desc = "A freezing pint of beer."
pH = 2
/datum/reagent/toxin/fakebeer/on_mob_life(mob/living/carbon/M)
switch(current_cycle)
@@ -343,6 +360,7 @@
reagent_state = SOLID
color = "#5B2E0D" // rgb: 91, 46, 13
toxpwr = 0.5
pH = 4.2
/datum/reagent/toxin/teapowder
name = "Ground Tea Leaves"
@@ -351,6 +369,7 @@
reagent_state = SOLID
color = "#7F8400" // rgb: 127, 132, 0
toxpwr = 0.5
pH = 4.9
/datum/reagent/toxin/mutetoxin //the new zombie powder.
name = "Mute Toxin"
@@ -359,6 +378,7 @@
color = "#F0F8FF" // rgb: 240, 248, 255
toxpwr = 0
taste_description = "silence"
pH = 12.2
/datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/M)
M.silent = max(M.silent, 3)
@@ -816,6 +836,7 @@
var/acidpwr = 10 //the amount of protection removed from the armour
taste_description = "acid"
self_consuming = TRUE
pH = 2.75
/datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume)
if(!istype(C))
@@ -17,6 +17,24 @@
var/mix_message = "The solution begins to bubble." //The message shown to nearby people upon mixing, if applicable
var/mix_sound = 'sound/effects/bubbles.ogg' //The sound played upon mixing, if applicable
//FermiChem!
var/OptimalTempMin = 200 // Lower area of bell curve for determining heat based rate reactions
var/OptimalTempMax = 800 // Upper end for above
var/ExplodeTemp = 900 // Temperature at which reaction explodes - If any reaction is this hot, it explodes!
var/OptimalpHMin = 5 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
var/OptimalpHMax = 10 // Higest value for above
var/ReactpHLim = 3 // How far out pH wil react, giving impurity place (Exponential phase)
var/CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)//Not implemented yet
var/CurveSharpT = 2 // How sharp the temperature exponential curve is (to the power of value)
var/CurveSharppH = 2 // How sharp the pH exponential curve is (to the power of value)
var/ThermicConstant = 1 // Temperature change per 1u produced
var/HIonRelease = 0.1 // pH change per 1u reaction
var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect
var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics
var/FermiExplode = FALSE // If the chemical explodes in a special way
var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this.
/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume, specialreact)
return
//I recommend you set the result amount to the total volume of all components.
@@ -41,6 +41,13 @@
results = list("aranesp" = 3)
required_reagents = list("epinephrine" = 1, "atropine" = 1, "morphine" = 1)
/datum/chemical_reaction/happiness
name = "Happiness"
id = "happiness"
results = list("happiness" = 4)
required_reagents = list("nitrous_oxide" = 2, "epinephrine" = 1, "ethanol" = 1)
required_catalysts = list("plasma" = 5)
/datum/chemical_reaction/skooma
name = "skooma"
id = "skooma"
@@ -178,6 +178,12 @@
results = list("mutadone" = 3)
required_reagents = list("mutagen" = 1, "acetone" = 1, "bromine" = 1)
/datum/chemical_reaction/neurine
name = "Neurine"
id = "neurine"
results = list("neurine" = 3)
required_reagents = list("mannitol" = 1, "acetone" = 1, "oxygen" = 1)
/datum/chemical_reaction/antihol
name = "antihol"
id = "antihol"
@@ -258,3 +264,9 @@
results = list("modafinil" = 5)
required_reagents = list("diethylamine" = 1, "ammonia" = 1, "phenol" = 1, "acetone" = 1, "sacid" = 1)
required_catalysts = list("bromine" = 1) // as close to the real world synthesis as possible
/datum/chemical_reaction/psicodine
name = "Psicodine"
id = "psicodine"
results = list("psicodine" = 5)
required_reagents = list( "mannitol" = 2, "water" = 2, "impedrezene" = 1)
@@ -528,6 +528,16 @@
/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume)
chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life") // Lol.
//This is missing, I'm adding it back (see tgwiki). Not sure why we don't have it.
/datum/chemical_reaction/life_friendly
name = "Life (Friendly)"
id = "life_friendly"
required_reagents = list("strange_reagent" = 1, "synthflesh" = 1, "sugar" = 1)
required_temp = 374
/datum/chemical_reaction/life_friendly/on_reaction(datum/reagents/holder, created_volume)
chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life (friendly)", FRIENDLY_SPAWN) //Pray for cute cats
/datum/chemical_reaction/corgium
name = "corgium"
id = "corgium"
+47 -1
View File
@@ -1,3 +1,6 @@
#define PH_WEAK (1 << 0)
#define TEMP_WEAK (1 << 1)
/obj/item/reagent_containers
name = "Container"
desc = "..."
@@ -12,6 +15,8 @@
var/spawned_disease = null
var/disease_amount = 20
var/spillable = FALSE
var/beaker_weakness_bitflag = NONE//Bitflag!
var/container_HP = 2
/obj/item/reagent_containers/Initialize(mapload, vol)
. = ..()
@@ -123,9 +128,50 @@
reagents.clear_reagents()
//melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
reagents.expose_temperature(1000)
if(beaker_weakness_bitflag & TEMP_WEAK)
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/H in seen)
to_chat(H, "<span class='notice'>[iconhtml] \The [src]'s melts from the temperature!</span>")
playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1)
qdel(src)
..()
//melts plastic beakers
/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
reagents.expose_temperature(exposed_temperature)
temp_check()
/obj/item/reagent_containers/proc/temp_check()
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)//assuming polypropylene
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts from the temperature!</span>")
playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1)
to_chat(M, "<span class='warning'><i>[iconhtml] Have you tried using glass or meta beakers for high temperature reactions? These are immune to temperature effects.</i></span>")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from temperature")
qdel(src)
//melts glass beakers
/obj/item/reagent_containers/proc/pH_check()
if(beaker_weakness_bitflag & PH_WEAK)
if((reagents.pH < 0.5) || (reagents.pH > 13.5))
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
container_HP--
if(container_HP <= 0)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts from the extreme pH!</span>")
playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from pH")
qdel(src)
else
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s is damaged by the extreme pH and begins to deform!</span>")
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
to_chat(M, "<span class='warning'><i>[iconhtml] Have you tried using plastic beakers (XL) or metabeakers for high pH reactions? These beakers are immune to pH effects.</i></span>")
@@ -240,7 +240,7 @@
name = "Rhinovirus culture bottle"
desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium."
spawned_disease = /datum/disease/advance/cold
/obj/item/reagent_containers/glass/bottle/flu_virion
name = "Flu virion culture bottle"
desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium."
@@ -6,6 +6,7 @@
reagent_flags = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
container_HP = 3
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
@@ -108,11 +109,13 @@
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 50 units."
desc = "A beaker. It can hold up to 50 units. Unable to withstand extreme pHes"
icon = 'icons/obj/chemical.dmi'
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
beaker_weakness_bitflag = PH_WEAK
container_HP = 5
/obj/item/reagent_containers/glass/beaker/Initialize()
. = ..()
@@ -152,27 +155,33 @@
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
desc = "A jar for honey. It can hold up to 50 units of sweet delight."
desc = "A jar for honey. It can hold up to 50 units of sweet delight. Unable to withstand reagents of an extreme pH."
icon = 'icons/obj/chemical.dmi'
icon_state = "vapour"
/obj/item/reagent_containers/glass/beaker/large
name = "large beaker"
desc = "A large beaker. Can hold up to 100 units."
desc = "A large beaker. Can hold up to 100 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerlarge"
materials = list(MAT_GLASS=2500)
volume = 100
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
container_HP = 6
/obj/item/reagent_containers/glass/beaker/plastic
name = "x-large beaker"
desc = "An extra-large beaker. Can hold up to 120 units."
desc = "An extra-large beaker. Can hold up to 150 units. Is able to resist acid and alkaline solutions, but melts at 444K"
icon_state = "beakerwhite"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
volume = 120
volume = 150
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,60,120)
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,150)
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
@@ -181,12 +190,16 @@
/obj/item/reagent_containers/glass/beaker/meta
name = "metamaterial beaker"
desc = "A large beaker. Can hold up to 180 units."
desc = "A large beaker. Can hold up to 200 units. Is able to withstand all chemical situations."
icon_state = "beakergold"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
volume = 180
volume = 200
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,60,120,180)
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,200)
/obj/item/reagent_containers/glass/beaker/meta/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
@@ -197,17 +210,24 @@
reagent_flags = OPENCONTAINER | NO_REACT
volume = 50
amount_per_transfer_from_this = 10
container_HP = 10//shouldn't be needed
/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
//reagents.set_reacting(FALSE) was this removed in a recent pr?
/obj/item/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
and Element Cuban combined with the Compound Pete. Can hold up to \
300 units."
300 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerbluespace"
materials = list(MAT_GLASS=3000)
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
container_HP = 8
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list("cryoxadone" = 30)
@@ -264,6 +284,11 @@
SLOT_L_STORE, SLOT_R_STORE,\
SLOT_GENERC_DEXTROUS_STORAGE
)
container_HP = 2
/obj/item/reagent_containers/glass/bucket/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/mop))
@@ -313,6 +338,11 @@
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
container_HP = 2
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/waterbottle/empty
list_reagents = list()
@@ -324,6 +354,7 @@
list_reagents = list("water" = 100)
volume = 100
amount_per_transfer_from_this = 20
container_HP = 2
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
list_reagents = list()
+259 -242
View File
@@ -1,242 +1,259 @@
/obj/item/reagent_containers/pill
name = "pill"
desc = "A tablet or capsule."
icon = 'icons/obj/chemical.dmi'
icon_state = "pill"
item_state = "pill"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
possible_transfer_amounts = list()
volume = 50
grind_results = list()
var/apply_type = INGEST
var/apply_method = "swallow"
var/roundstart = 0
var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
var/dissolvable = TRUE
/obj/item/reagent_containers/pill/Initialize()
. = ..()
if(!icon_state)
icon_state = "pill[rand(1,20)]"
if(reagents.total_volume && roundstart)
name += " ([reagents.total_volume]u)"
/obj/item/reagent_containers/pill/attack_self(mob/user)
return
/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone)
if(!canconsume(M, user))
return 0
if(M == user)
M.visible_message("<span class='notice'>[user] attempts to [apply_method] [src].</span>")
if(self_delay)
if(!do_mob(user, M, self_delay))
return 0
to_chat(M, "<span class='notice'>You [apply_method] [src].</span>")
else
M.visible_message("<span class='danger'>[user] attempts to force [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] attempts to force [M] to [apply_method] [src].</span>")
if(!do_mob(user, M))
return 0
M.visible_message("<span class='danger'>[user] forces [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] forces [M] to [apply_method] [src].</span>")
var/makes_me_think = pick(strings("redpill.json", "redpill_questions"))
if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "<span class='notice'>[makes_me_think]</span>"), 50)
log_combat(user, M, "fed", reagents.log_list())
if(reagents.total_volume)
reagents.reaction(M, apply_type)
reagents.trans_to(M, reagents.total_volume)
qdel(src)
return 1
/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity)
. = ..()
if(!proximity)
return
if(!dissolvable || !target.is_refillable())
return
if(target.is_drainable() && !target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty! There's nothing to dissolve [src] in.</span>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
to_chat(user, "<span class='notice'>You dissolve [src] in [target].</span>")
for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius
to_chat(O, "<span class='warning'>[user] slips something into [target]!</span>")
reagents.trans_to(target, reagents.total_volume)
qdel(src)
/obj/item/reagent_containers/pill/tox
name = "toxins pill"
desc = "Highly toxic."
icon_state = "pill5"
list_reagents = list("toxin" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/cyanide
name = "cyanide pill"
desc = "Don't swallow this."
icon_state = "pill5"
list_reagents = list("cyanide" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/adminordrazine
name = "adminordrazine pill"
desc = "It's magic. We don't have to explain it."
icon_state = "pill16"
list_reagents = list("adminordrazine" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/morphine
name = "morphine pill"
desc = "Commonly used to treat insomnia."
icon_state = "pill8"
list_reagents = list("morphine" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/stimulant
name = "stimulant pill"
desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
icon_state = "pill19"
list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/salbutamol
name = "salbutamol pill"
desc = "Used to treat oxygen deprivation."
icon_state = "pill16"
list_reagents = list("salbutamol" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/charcoal
name = "charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
list_reagents = list("charcoal" = 10)
roundstart = 1
/obj/item/reagent_containers/pill/epinephrine
name = "epinephrine pill"
desc = "Used to stabilize patients."
icon_state = "pill5"
list_reagents = list("epinephrine" = 15)
roundstart = 1
/obj/item/reagent_containers/pill/mannitol
name = "mannitol pill"
desc = "Used to treat brain damage."
icon_state = "pill17"
list_reagents = list("mannitol" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/mutadone
name = "mutadone pill"
desc = "Used to treat genetic damage."
icon_state = "pill20"
list_reagents = list("mutadone" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/salicyclic
name = "salicylic acid pill"
desc = "Used to dull pain."
icon_state = "pill9"
list_reagents = list("sal_acid" = 24)
roundstart = 1
/obj/item/reagent_containers/pill/oxandrolone
name = "oxandrolone pill"
desc = "Used to stimulate burn healing."
icon_state = "pill11"
list_reagents = list("oxandrolone" = 24)
roundstart = 1
/obj/item/reagent_containers/pill/insulin
name = "insulin pill"
desc = "Handles hyperglycaemic coma."
icon_state = "pill18"
list_reagents = list("insulin" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/antirad
name = "potassium iodide pill"
desc = "Used to treat radition used to counter radiation poisoning."
icon_state = "pill18"
list_reagents = list("potass_iodide" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/antirad_plus
name = "prussian blue pill"
desc = "Used to treat heavy radition poisoning."
icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "prussian_blue"
list_reagents = list("prussian_blue" = 25, "water" = 10)
roundstart = 1
/obj/item/reagent_containers/pill/mutarad
name = "radiation treatment deluxe pill"
desc = "Used to treat heavy radition poisoning and genetic defects."
icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "anit_rad_fixgene"
list_reagents = list("prussian_blue" = 15, "potass_iodide" = 15, "mutadone" = 15, "water" = 5)
roundstart = 1
///////////////////////////////////////// this pill is used only in a legion mob drop
/obj/item/reagent_containers/pill/shadowtoxin
name = "black pill"
desc = "I wouldn't eat this if I were you."
icon_state = "pill9"
color = "#454545"
list_reagents = list("shadowmutationtoxin" = 1)
//////////////////////////////////////// drugs
/obj/item/reagent_containers/pill/zoom
name = "zoom pill"
list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1)
/obj/item/reagent_containers/pill/happy
name = "happy pill"
list_reagents = list("sugar" = 10, "space_drugs" = 10)
/obj/item/reagent_containers/pill/lsd
name = "hallucinogen pill"
list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15)
/obj/item/reagent_containers/pill/aranesp
name = "speedy pill"
list_reagents = list("aranesp" = 10)
/obj/item/reagent_containers/pill/floorpill
name = "floorpill"
desc = "A strange pill found in the depths of maintenance"
icon_state = "pill21"
var/static/list/names = list("maintenance pill","floorpill","mystery pill","suspicious pill","strange pill")
var/static/list/descs = list("Your feeling is telling you no, but...","Drugs are expensive, you can't afford not to eat any pills that you find."\
, "Surely, there's no way this could go bad.")
/obj/item/reagent_containers/pill/floorpill/Initialize()
list_reagents = list(get_random_reagent_id() = rand(10,50))
. = ..()
name = pick(names)
if(prob(20))
desc = pick(descs)
/obj/item/reagent_containers/pill/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/pill/penis_enlargement
name = "penis enlargement pill"
list_reagents = list("penis_enlargement" = 30)
/obj/item/reagent_containers/pill
name = "pill"
desc = "A tablet or capsule."
icon = 'icons/obj/chemical.dmi'
icon_state = "pill"
item_state = "pill"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
possible_transfer_amounts = list()
volume = 50
grind_results = list()
var/apply_type = INGEST
var/apply_method = "swallow"
var/roundstart = 0
var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
var/dissolvable = TRUE
/obj/item/reagent_containers/pill/Initialize()
. = ..()
if(!icon_state)
icon_state = "pill[rand(1,20)]"
if(reagents.total_volume && roundstart)
name += " ([reagents.total_volume]u)"
/obj/item/reagent_containers/pill/attack_self(mob/user)
return
/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone)
if(!canconsume(M, user))
return 0
if(M == user)
M.visible_message("<span class='notice'>[user] attempts to [apply_method] [src].</span>")
if(self_delay)
if(!do_mob(user, M, self_delay))
return 0
to_chat(M, "<span class='notice'>You [apply_method] [src].</span>")
else
M.visible_message("<span class='danger'>[user] attempts to force [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] attempts to force [M] to [apply_method] [src].</span>")
if(!do_mob(user, M))
return 0
M.visible_message("<span class='danger'>[user] forces [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] forces [M] to [apply_method] [src].</span>")
var/makes_me_think = pick(strings("redpill.json", "redpill_questions"))
if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "<span class='notice'>[makes_me_think]</span>"), 50)
log_combat(user, M, "fed", reagents.log_list())
if(reagents.total_volume)
reagents.reaction(M, apply_type)
reagents.trans_to(M, reagents.total_volume)
qdel(src)
return 1
/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity)
. = ..()
if(!proximity)
return
if(!dissolvable || !target.is_refillable())
return
if(target.is_drainable() && !target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty! There's nothing to dissolve [src] in.</span>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
to_chat(user, "<span class='notice'>You dissolve [src] in [target].</span>")
for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius
to_chat(O, "<span class='warning'>[user] slips something into [target]!</span>")
reagents.trans_to(target, reagents.total_volume)
qdel(src)
/obj/item/reagent_containers/pill/tox
name = "toxins pill"
desc = "Highly toxic."
icon_state = "pill5"
list_reagents = list("toxin" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/cyanide
name = "cyanide pill"
desc = "Don't swallow this."
icon_state = "pill5"
list_reagents = list("cyanide" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/adminordrazine
name = "adminordrazine pill"
desc = "It's magic. We don't have to explain it."
icon_state = "pill16"
list_reagents = list("adminordrazine" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/morphine
name = "morphine pill"
desc = "Commonly used to treat insomnia."
icon_state = "pill8"
list_reagents = list("morphine" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/stimulant
name = "stimulant pill"
desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
icon_state = "pill19"
list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/salbutamol
name = "salbutamol pill"
desc = "Used to treat oxygen deprivation."
icon_state = "pill16"
list_reagents = list("salbutamol" = 30)
roundstart = 1
/obj/item/reagent_containers/pill/charcoal
name = "charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
list_reagents = list("charcoal" = 10)
roundstart = 1
/obj/item/reagent_containers/pill/epinephrine
name = "epinephrine pill"
desc = "Used to stabilize patients."
icon_state = "pill5"
list_reagents = list("epinephrine" = 15)
roundstart = 1
/obj/item/reagent_containers/pill/mannitol
name = "mannitol pill"
desc = "Used to treat brain damage."
icon_state = "pill17"
list_reagents = list("mannitol" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/mutadone
name = "mutadone pill"
desc = "Used to treat genetic damage."
icon_state = "pill20"
list_reagents = list("mutadone" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/salicyclic
name = "salicylic acid pill"
desc = "Used to dull pain."
icon_state = "pill9"
list_reagents = list("sal_acid" = 24)
roundstart = 1
/obj/item/reagent_containers/pill/oxandrolone
name = "oxandrolone pill"
desc = "Used to stimulate burn healing."
icon_state = "pill11"
list_reagents = list("oxandrolone" = 24)
roundstart = 1
/obj/item/reagent_containers/pill/insulin
name = "insulin pill"
desc = "Handles hyperglycaemic coma."
icon_state = "pill18"
list_reagents = list("insulin" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/psicodine
name = "psicodine pill"
desc = "Used to treat mental instability and traumas."
list_reagents = list("psicodine" = 10)
icon_state = "pill22"
roundstart = 1
/obj/item/reagent_containers/pill/antirad
name = "potassium iodide pill"
desc = "Used to treat radition used to counter radiation poisoning."
icon_state = "pill18"
list_reagents = list("potass_iodide" = 50)
roundstart = 1
/obj/item/reagent_containers/pill/antirad_plus
name = "prussian blue pill"
desc = "Used to treat heavy radition poisoning."
icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "prussian_blue"
list_reagents = list("prussian_blue" = 25, "water" = 10)
roundstart = 1
/obj/item/reagent_containers/pill/mutarad
name = "radiation treatment deluxe pill"
desc = "Used to treat heavy radition poisoning and genetic defects."
icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "anit_rad_fixgene"
list_reagents = list("prussian_blue" = 15, "potass_iodide" = 15, "mutadone" = 15, "water" = 5)
roundstart = 1
///////////////////////////////////////// this pill is used only in a legion mob drop
/obj/item/reagent_containers/pill/shadowtoxin
name = "black pill"
desc = "I wouldn't eat this if I were you."
icon_state = "pill9"
color = "#454545"
list_reagents = list("shadowmutationtoxin" = 1)
//////////////////////////////////////// drugs
/obj/item/reagent_containers/pill/zoom
name = "zoom pill"
list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1)
/obj/item/reagent_containers/pill/happy
name = "happy pill"
list_reagents = list("sugar" = 10, "space_drugs" = 10)
/obj/item/reagent_containers/pill/lsd
name = "hallucinogen pill"
list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15)
/obj/item/reagent_containers/pill/aranesp
name = "speedy pill"
list_reagents = list("aranesp" = 10)
/obj/item/reagent_containers/pill/happiness
name = "happiness pill"
desc = "It has a creepy smiling face on it."
icon_state = "pill_happy"
list_reagents = list("happiness" = 10)
/obj/item/reagent_containers/pill/floorpill
name = "floorpill"
desc = "A strange pill found in the depths of maintenance"
icon_state = "pill21"
var/static/list/names = list("maintenance pill","floorpill","mystery pill","suspicious pill","strange pill")
var/static/list/descs = list("Your feeling is telling you no, but...","Drugs are expensive, you can't afford not to eat any pills that you find."\
, "Surely, there's no way this could go bad.")
/obj/item/reagent_containers/pill/floorpill/Initialize()
list_reagents = list(get_random_reagent_id() = rand(10,50))
. = ..()
name = pick(names)
if(prob(20))
desc = pick(descs)
/obj/item/reagent_containers/pill/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/pill/penis_enlargement
name = "penis enlargement pill"
list_reagents = list("penis_enlarger" = 10)
/obj/item/reagent_containers/pill/breast_enlargement
name = "breast enlargement pill"
list_reagents = list("breast_enlarger" = 10)
@@ -554,6 +554,16 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_tongue
name = "Cybernetic tongue"
desc = "A fancy cybernetic tongue."
id = "cybernetic_tongue"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500)
build_path = /obj/item/organ/tongue/cybernetic
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/////////////////////
//Adv Surgery Tools//
/////////////////////
+10 -1
View File
@@ -1,4 +1,3 @@
/////////////////////////////////////////
/////////////////HUDs////////////////////
/////////////////////////////////////////
@@ -480,6 +479,16 @@
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/pHmeter
name = "Chemical Analyser"
desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution."
id = "pHmeter"
build_type = PROTOLATHE
materials = list(MAT_METAL = 1000, MAT_SILVER = 100, MAT_DIAMOND = 100)
build_path = /obj/item/fermichem/pHmeter
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/////////////////////////////////////////
////////////Armour///////////////////////
/////////////////////////////////////////
@@ -93,7 +93,7 @@
/datum/nanite_program/blood_restoring/check_conditions()
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
if(C.blood_volume >= BLOOD_VOLUME_SAFE)
if(C.blood_volume >= (BLOOD_VOLUME_SAFE*C.blood_ratio))
return FALSE
else
return FALSE
@@ -256,4 +256,3 @@
log_game("[C] has been successfully defibrillated by nanites.")
else
playsound(C, 'sound/machines/defib_failed.ogg', 50, 0)
+2 -2
View File
@@ -69,7 +69,7 @@
display_name = "Advanced Biotechnology"
description = "Advanced Biotechnology"
prereq_ids = list("biotech")
design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart")
design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart", "pHmeter")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -526,7 +526,7 @@
display_name = "Cybernetic Organs"
description = "We have the technology to rebuild him."
prereq_ids = list("adv_biotech")
design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u")
design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u", "cybernetic_tongue")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
+4
View File
@@ -60,6 +60,10 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
for(var/a in T.GetAllContents())
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
return FALSE
if(istype(a, /obj/structure/closet))//Prevents eigenlockers from ending up at CC
var/obj/structure/closet/c = a
if(c.eigen_teleport == TRUE)
return FALSE
return TRUE
/obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S)
@@ -15,7 +15,6 @@
var/die_with_shapeshifted_form = TRUE
var/convert_damage = FALSE //If you want to convert the caster's health to the shift, and vice versa.
var/convert_damage_type = BRUTE //Since simplemobs don't have advanced damagetypes, what to convert damage back into.
var/shapeshift_type
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
/mob/living/simple_animal/pet/dog/corgi,\
@@ -167,4 +166,4 @@
/datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer)
if(source)
source.shapeDeath(gibbed)
source.shapeDeath(gibbed)
+32
View File
@@ -1,6 +1,7 @@
#define LIVER_DEFAULT_HEALTH 100 //amount of damage required for liver failure
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
#define LIVER_SWELLING_MOVE_MODIFY "pharma"
/obj/item/organ/liver
name = "liver"
@@ -16,6 +17,8 @@
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins
var/swelling = 0
var/cachedmoveCalc = 1
/obj/item/organ/liver/on_life()
var/mob/living/carbon/C = owner
@@ -45,11 +48,40 @@
if(damage > maxHealth)//cap liver damage
damage = maxHealth
if(swelling >= 10)
pharmacokinesis()
/obj/item/organ/liver/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("iron", 5)
return S
//Just in case
/obj/item/organ/liver/Remove(mob/living/carbon/M, special = 0)
..()
M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY)
M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret.
sizeMoveMod(1, M)
//Applies some of the effects to the patient.
/obj/item/organ/liver/proc/pharmacokinesis()
var/moveCalc = 1+((round(swelling) - 9)/3)
if(moveCalc == cachedmoveCalc)//reduce calculations
return
if(prob(5))
to_chat(owner, "<span class='notice'>You feel a stange ache in your side, almost like a sitch. This pain is affecting your movements and making you feel lightheaded.</span>")
var/mob/living/carbon/human/H = owner
H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
H.AdjustBloodVol(moveCalc/3)
sizeMoveMod(moveCalc, H)
/obj/item/organ/liver/proc/sizeMoveMod(var/value, mob/living/carbon/human/H)
if(cachedmoveCalc == value)
return
H.next_move_modifier /= cachedmoveCalc
H.next_move_modifier *= value
cachedmoveCalc = value
/obj/item/organ/liver/fly
name = "insectoid liver"
icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits.
+50 -4
View File
@@ -1,3 +1,5 @@
#define LUNGS_MAX_HEALTH 300
/obj/item/organ/lungs
name = "lungs"
icon_state = "lungs"
@@ -54,8 +56,40 @@
var/crit_stabilizing_reagent = "epinephrine"
//health
var/maxHealth = LUNGS_MAX_HEALTH
var/damage = 0
//TODO: lung health affects lung function
/obj/item/organ/lungs/proc/adjustLungLoss(damage_mod, mob/living/carbon/M) //damage might be too low atm.
if (maxHealth == INFINITY)
return
if(damage+damage_mod < 0)
damage = 0
return
damage += damage_mod
if ((damage / maxHealth) > 1)
to_chat(M, "<span class='userdanger'>You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore!</span>")
M.emote("gasp")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Lungs lost")
qdel(src)
else if ((damage / maxHealth) > 0.75)
to_chat(M, "<span class='warning'>It's getting really hard to breathe!!</span>")
M.emote("gasp")
M.Dizzy(3)
else if ((damage / maxHealth) > 0.5)
M.Dizzy(2)
to_chat(M, "<span class='notice'>Your chest is really starting to hurt.</span>")
M.emote("cough")
else if ((damage / maxHealth) > 0.2)
to_chat(M, "<span class='notice'>You feel an ache within your chest.</span>")
M.emote("cough")
M.Dizzy(1)
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
//TODO: add lung damage = less oxygen gains
var/breathModifier = (5-(5*(damage/maxHealth)/2)) //range 2.5 - 5
if((H.status_flags & GODMODE))
return
if(HAS_TRAIT(H, TRAIT_NOBREATH))
@@ -124,7 +158,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half
gas_breathed = breath_gases[/datum/gas/oxygen]
H.clear_alert("not_enough_oxy")
@@ -153,7 +187,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/nitrogen]
H.clear_alert("nitro")
@@ -190,7 +224,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/carbon_dioxide]
H.clear_alert("not_enough_co2")
@@ -220,7 +254,7 @@
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-5)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/plasma]
H.clear_alert("not_enough_tox")
@@ -244,6 +278,9 @@
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "chemical_euphoria", /datum/mood_event/chemical_euphoria)
else
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
// BZ
@@ -368,10 +405,13 @@
var/cold_modifier = H.dna.species.coldmod
if(breath_temperature < cold_level_3_threshold)
H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type)
adjustLungLoss((cold_level_3_damage*cold_modifier*2), H)
if(breath_temperature > cold_level_3_threshold && breath_temperature < cold_level_2_threshold)
H.apply_damage_type(cold_level_2_damage*cold_modifier, cold_damage_type)
adjustLungLoss((cold_level_2_damage*cold_modifier*2), H)
if(breath_temperature > cold_level_2_threshold && breath_temperature < cold_level_1_threshold)
H.apply_damage_type(cold_level_1_damage*cold_modifier, cold_damage_type)
adjustLungLoss((cold_level_1_damage*cold_modifier*2), H)
if(breath_temperature < cold_level_1_threshold)
if(prob(20))
to_chat(H, "<span class='warning'>You feel [cold_message] in your [name]!</span>")
@@ -380,10 +420,13 @@
var/heat_modifier = H.dna.species.heatmod
if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold)
H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type)
adjustLungLoss((heat_level_1_damage*heat_modifier*2), H)
if(breath_temperature > heat_level_2_threshold && breath_temperature < heat_level_3_threshold)
H.apply_damage_type(heat_level_2_damage*heat_modifier, heat_damage_type)
adjustLungLoss((heat_level_2_damage*heat_modifier*2), H)
if(breath_temperature > heat_level_3_threshold)
H.apply_damage_type(heat_level_3_damage*heat_modifier, heat_damage_type)
adjustLungLoss((heat_level_3_damage*heat_modifier*2), H)
if(breath_temperature > heat_level_1_threshold)
if(prob(20))
to_chat(H, "<span class='warning'>You feel [hot_message] in your [name]!</span>")
@@ -402,12 +445,14 @@
safe_oxygen_max = 0 // Like, at all.
safe_toxins_min = 16 //We breath THIS!
safe_toxins_max = 0
maxHealth = INFINITY//I don't understand how plamamen work, so I'm not going to try t give them special lungs atm
/obj/item/organ/lungs/cybernetic
name = "cybernetic lungs"
desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement."
icon_state = "lungs-c"
synthetic = TRUE
maxHealth = 400
/obj/item/organ/lungs/cybernetic/emp_act()
. = ..()
@@ -427,6 +472,7 @@
cold_level_1_threshold = 200
cold_level_2_threshold = 140
cold_level_3_threshold = 100
maxHealth = 550
/obj/item/organ/lungs/ashwalker
name = "ash lungs"
@@ -153,6 +153,17 @@
// if they have no mutant tongues, give them a regular one
T.Insert(src)
else
var/obj/item/organ/tongue/oT = getorganslot(ORGAN_SLOT_TONGUE)
if(oT.name == "fluffy tongue")
var/obj/item/organ/tongue/T
if(dna && dna.species && dna.species.mutanttongue)
T = new dna.species.mutanttongue()
else
T = new()
oT.Remove(src)
qdel(oT)
T.Insert(src)
if(!getorganslot(ORGAN_SLOT_EYES))
var/obj/item/organ/eyes/E
+67 -1
View File
@@ -1,3 +1,5 @@
#define TONGUE_MAX_HEALTH 60
/obj/item/organ/tongue
name = "tongue"
desc = "A fleshy muscle mostly used for lying."
@@ -8,6 +10,8 @@
var/list/languages_possible
var/say_mod = null
var/taste_sensitivity = 15 // lower is more sensitive.
var/maxHealth = TONGUE_MAX_HEALTH
var/damage = 0
var/modifies_speech = FALSE
var/static/list/languages_possible_base = typecacheof(list(
/datum/language/common,
@@ -27,6 +31,29 @@
/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args)
/obj/item/organ/tongue/proc/adjustTongueLoss(mob/living/carbon/M, damage_mod)
if (maxHealth == "alien")
return
if (maxHealth == "bone")
var/target = M.get_bodypart(BODY_ZONE_HEAD)
M.apply_damage(damage_mod, BURN, target)
to_chat(M, "<span class='userdanger'>The drink burns your skull! Oof, your bones!</span>")
return
if(damage+damage_mod < 0)
damage = 0
return
damage += damage_mod
if ((damage / maxHealth) > 1)
to_chat(M, "<span class='userdanger'>Your tongue is singed beyond recognition, and disintegrates!</span>")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Tongues lost to Fermi")
qdel(src)
else if ((damage / maxHealth) > 0.85)
to_chat(M, "<span class='warning'>Your tongue feels like it's about to fall out!.</span>")
else if ((damage / maxHealth) > 0.5)
to_chat(M, "<span class='notice'>Your tongue is really starting to hurt.</span>")
/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0)
..()
if(say_mod && M.dna && M.dna.species)
@@ -51,6 +78,7 @@
icon_state = "tonguelizard"
say_mod = "hisses"
taste_sensitivity = 10 // combined nose + tongue, extra sensitive
maxHealth = 40 //extra sensitivity means tongue is more susceptible to damage
modifies_speech = TRUE
/obj/item/organ/tongue/lizard/handle_speech(datum/source, list/speech_args)
@@ -68,6 +96,7 @@
icon_state = "tonguefly"
say_mod = "buzzes"
taste_sensitivity = 25 // you eat vomit, this is a mercy
maxHealth = 80 //years of eatting trash has made your tongue strong
modifies_speech = TRUE
/obj/item/organ/tongue/fly/handle_speech(datum/source, list/speech_args)
@@ -85,6 +114,7 @@
icon_state = "tongueayylmao"
say_mod = "gibbers"
taste_sensitivity = 101 // ayys cannot taste anything.
maxHealth = 120 //Ayys probe a lot
modifies_speech = TRUE
/obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args)
@@ -113,6 +143,7 @@
icon_state = "tonguezombie"
say_mod = "moans"
taste_sensitivity = 32
maxHealth = 65 //Stop! It's already dead...!
modifies_speech = TRUE
/obj/item/organ/tongue/zombie/handle_speech(datum/source, list/speech_args)
@@ -137,6 +168,7 @@
icon_state = "tonguexeno"
say_mod = "hisses"
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
maxHealth = "alien" //Their blood is acid, so, no, though a tongueless xeno might be funny
modifies_speech = TRUE // not really, they just hiss
var/static/list/languages_possible_alien = typecacheof(list(
/datum/language/xenocommon,
@@ -159,6 +191,7 @@
say_mod = "rattles"
attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned")
taste_sensitivity = 101 // skeletons cannot taste anything
maxHealth = "bone" //Take brute damage instead
modifies_speech = TRUE
var/chattering = FALSE
var/phomeme_type = "sans"
@@ -181,6 +214,7 @@
name = "plasma bone \"tongue\""
desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech."
icon_state = "tongueplasma"
maxHealth = "alien"
modifies_speech = FALSE
/obj/item/organ/tongue/robot
@@ -192,6 +226,7 @@
attack_verb = list("beeped", "booped")
modifies_speech = TRUE
taste_sensitivity = 25 // not as good as an organic tongue
maxHealth = 100 //RoboTongue!
var/electronics_magic = TRUE
/obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt)
@@ -200,8 +235,39 @@
/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
/obj/item/organ/tongue/fluffy
name = "fluffy tongue"
desc = "OwO what's this?"
icon_state = "tonguefluffy"
taste_sensitivity = 10 // extra sensitive and inquisitive uwu
maxHealth = 35 //Sensitive tongue!
modifies_speech = TRUE
/obj/item/organ/tongue/fluffy/handle_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(copytext(message, 1, 2) != "*")
message = replacetext(message, "ne", "nye")
message = replacetext(message, "nu", "nyu")
message = replacetext(message, "na", "nya")
message = replacetext(message, "no", "nyo")
message = replacetext(message, "ove", "uv")
message = replacetext(message, "l", "w")
message = replacetext(message, "r", "w")
message = lowertext(message)
speech_args[SPEECH_MESSAGE] = message
/obj/item/organ/tongue/cybernetic
name = "cybernetic tongue"
desc = "A state of the art robotic tongue that can detect the pH of anything drank."
icon_state = "tonguecybernetic"
taste_sensitivity = 10
maxHealth = 60 //It's robotic!
/obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
/obj/item/organ/tongue/robot/ipc
name = "positronic voicebox"
say_mod = "beeps"
desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms."
electronics_magic = FALSE
electronics_magic = FALSE
+862 -1
View File
@@ -575,7 +575,7 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/carbon/human/H = V
if(H.canbearoused && H.has_dna()) // probably a redundant check but for good measure
if(H.canbearoused && H.has_dna() && HAS_TRAIT(H, TRAIT_NYMPHO)) // probably a redundant check but for good measure
H.mob_climax(forced_climax=TRUE)
//DAB
@@ -608,6 +608,867 @@
return cooldown
//////////////////////////////////////
///////ENTHRAL VELVET CHORDS//////////
//////////////////////////////////////
//Heavily modified voice of god code
/obj/item/organ/vocal_cords/velvet
name = "Velvet chords"
desc = "The voice spoken from these just make you want to drift off, sleep and obey."
icon_state = "velvet_chords"
actions_types = list(/datum/action/item_action/organ_action/velvet)
spans = list("velvet")
/datum/action/item_action/organ_action/velvet
name = "Velvet chords"
var/obj/item/organ/vocal_cords/velvet/cords = null
//icon_icon = 'icons/mob/screen_alert.dmi'
//button_icon_state = "velvet_chords"
//icon = 'icons/mob/screen_alert.dmi'
//icon_state = "in_love"
/datum/action/item_action/organ_action/velvet/New()
..()
cords = target
/datum/action/item_action/organ_action/velvet/IsAvailable()
return TRUE
/datum/action/item_action/organ_action/velvet/Trigger()
. = ..()
var/command = input(owner, "Speak in a sultry tone", "Command")
if(QDELETED(src) || QDELETED(owner))
return
if(!command)
return
owner.say(".x[command]")
/obj/item/organ/vocal_cords/velvet/can_speak_with()
return TRUE
/obj/item/organ/vocal_cords/velvet/handle_speech(message) //actually say the message
owner.say(message, spans = spans, sanitize = FALSE)
velvetspeech(message, owner, 1)
//////////////////////////////////////
///////////FermiChem//////////////////
//////////////////////////////////////
//Removed span_list from input arguments.
/proc/velvetspeech(message, mob/living/user, base_multiplier = 1, message_admins = FALSE, debug = FALSE)
if(!user || !user.can_speak() || user.stat)
return 0 //no cooldown
var/log_message = message
//FIND THRALLS
message = lowertext(message)
var/mob/living/list/listeners = list()
for(var/mob/living/L in get_hearers_in_view(8, user))
if(L.can_hear() && !L.anti_magic_check(FALSE, TRUE) && L.stat != DEAD)
if(L.has_status_effect(/datum/status_effect/chem/enthrall))//Check to see if they have the status
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)//Check to see if pet is on cooldown from last command and if the master is right
if(E.master != user)
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
if (E.cooldown > 0)//If they're on cooldown you can't give them more commands.
continue
listeners += L
if(!listeners.len)
return 0
//POWER CALCULATIONS
var/power_multiplier = base_multiplier
// Not sure I want to give extra power to anyone at the moment...? We'll see how it turns out
if(user.mind)
//Chaplains are very good at indoctrinating
if(user.mind.assigned_role == "Chaplain")
power_multiplier *= 1.2
//Command staff has authority
if(user.mind.assigned_role in GLOB.command_positions)
power_multiplier *= 1.1
//Why are you speaking
if(user.mind.assigned_role == "Mime")
power_multiplier *= 0.5
//Cultists are closer to their gods and are better at indoctrinating
if(iscultist(user))
power_multiplier *= 1.2
else if (is_servant_of_ratvar(user))
power_multiplier *= 1.2
else if (is_devil(user))//The devil is supposed to be seductive, right?
power_multiplier *= 1.2
//range = 0.5 - 1.4~
//most cases = 1
//Try to check if the speaker specified a name or a job to focus on
var/list/specific_listeners = list()
var/found_string = null
//Get the proper job titles
message = get_full_job_name(message)
for(var/V in listeners)
var/mob/living/L = V
if(dd_hasprefix(message, L.real_name))
specific_listeners += L //focus on those with the specified name
//Cut out the name so it doesn't trigger commands
found_string = L.real_name
power_multiplier += 0.5
else if(dd_hasprefix(message, L.first_name()))
specific_listeners += L //focus on those with the specified name
//Cut out the name so it doesn't trigger commands
found_string = L.first_name()
power_multiplier += 0.5
else if(L.mind && L.mind.assigned_role && dd_hasprefix(message, L.mind.assigned_role))
specific_listeners += L //focus on those with the specified job
//Cut out the job so it doesn't trigger commands
found_string = L.mind.assigned_role
power_multiplier += 0.25
if(specific_listeners.len)
listeners = specific_listeners
//power_multiplier *= (1 + (1/specific_listeners.len)) //Put this is if it becomes OP, power is judged internally on a thrall, so shouldn't be nessicary.
message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1)//I have no idea what this does
var/obj/item/organ/tongue/T = user.getorganslot(ORGAN_SLOT_TONGUE)
if (T.name == "fluffy tongue") //If you sound hillarious, it's hard to take you seriously. This is a way for other players to combat/reduce their effectiveness.
power_multiplier *= 0.75
if(debug == TRUE)
to_chat(world, "[user]'s power is [power_multiplier].")
//Mixables
var/static/regex/enthral_words = regex("relax|obey|love|serve|docile|so easy|ara ara")
var/static/regex/reward_words = regex("good boy|good girl|good pet|good job")
var/static/regex/punish_words = regex("bad boy|bad girl|bad pet|bad job")
//phase 0
var/static/regex/saymyname_words = regex("say my name|who am i|whoami")
var/static/regex/wakeup_words = regex("revert|awaken|snap") //works
//phase1
var/static/regex/petstatus_words = regex("how are you|what is your status|are you okay")
var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush")
var/static/regex/speak_words = regex("talk to me|speak")
var/static/regex/antiresist_words = regex("unable to resist|give in")//useful if you think your target is resisting a lot
var/static/regex/resist_words = regex("resist|snap out of it|fight")//useful if two enthrallers are fighting
var/static/regex/forget_words = regex("forget|muddled|awake and forget")
var/static/regex/attract_words = regex("come here|come to me|get over here|attract")
//phase 2
var/static/regex/orgasm_words = regex("cum|orgasm|climax|squirt|heyo") //wah, lewd
var/static/regex/awoo_words = regex("howl|awoo|bark")
var/static/regex/nya_words = regex("nya|meow|mewl")
var/static/regex/sleep_words = regex("sleep|slumber|rest")
var/static/regex/strip_words = regex("strip|derobe|nude")
var/static/regex/walk_words = regex("slow down|walk")
var/static/regex/run_words = regex("run|speed up")
var/static/regex/liedown_words = regex("lie down") //TO ADD
var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown|kneel")
//phase 3
var/static/regex/statecustom_words = regex("state triggers|state your triggers")
var/static/regex/custom_words = regex("new trigger|listen to me")
var/static/regex/custom_words_words = regex("speak|echo|shock|cum|kneel|strip|trance")//What a descriptive name!
var/static/regex/custom_echo = regex("obsess|fills your mind|loop")
var/static/regex/instill_words = regex("feel|entice|overwhel")
var/static/regex/recognise_words = regex("recognise me|did you miss me?")
var/static/regex/objective_words = regex("new objective|obey this command|unable to resist|compulsed")
var/static/regex/heal_words = regex("live|heal|survive|mend|life|pets never die")
var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt")
var/static/regex/hallucinate_words = regex("get high|hallucinate")
var/static/regex/hot_words = regex("heat|hot|hell")
var/static/regex/cold_words = regex("cold|cool down|chill|freeze")
var/static/regex/getup_words = regex("get up")
var/static/regex/pacify_words = regex("more and more docile|complaisant|friendly|pacifist")
var/static/regex/charge_words = regex("charge|oorah|attack")
var/distancelist = list(2,2,1.5,1.3,1.15,1,0.8,0.6,0.5,0.25)
//CALLBACKS ARE USED FOR MESSAGES BECAUSE SAY IS HANDLED AFTER THE PROCESSING.
//Tier 1
//ENTHRAL mixable (works I think)
if(findtext(message, enthral_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
power_multiplier *= distancelist[get_dist(user, V)+1]
if(L == user)
continue
if(length(message))
E.enthrallTally += (power_multiplier*(((length(message))/200) + 1)) //encourage players to say more than one word.
else
E.enthrallTally += power_multiplier*1.25 //thinking about it, I don't know how this can proc
if(L.canbearoused)
if(L.client?.prefs.lewdchem)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='nicegreen'><i><b>[E.enthrallGender] is so nice to listen to.</b></i></span>"), 5)
E.cooldown += 1
//REWARD mixable works
if(findtext(message, reward_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
power_multiplier *= distancelist[get_dist(user, V)+1]
if(L == user)
continue
if (L.client?.prefs.lewdchem)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='love'>[E.enthrallGender] has praised me!!</span>"), 5)
if(HAS_TRAIT(L, TRAIT_NYMPHO))
L.adjustArousalLoss(2*power_multiplier)
if(HAS_TRAIT(L, TRAIT_MASO))
E.enthrallTally -= power_multiplier
E.resistanceTally += power_multiplier
E.cooldown += 1
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='nicegreen'><b><i>I've been praised for doing a good job!</b></i></span>"), 5)
E.resistanceTally -= power_multiplier
E.enthrallTally += power_multiplier
var/descmessage = "<span class='love'><i>[(L.client?.prefs.lewdchem?"I feel so happy! I'm a good pet who [E.enthrallGender] loves!":"I did a good job!")]</i></span>"
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallpraise", /datum/mood_event/enthrallpraise, descmessage)
E.cooldown += 1
//PUNISH mixable works
else if(findtext(message, punish_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
var/descmessage = "[(L.client?.prefs.lewdchem?"I've failed [E.enthrallGender]... What a bad, bad pet!":"I did a bad job...")]"
if(L == user)
continue
if (L.client?.prefs.lewdchem)
if(HAS_TRAIT(L, TRAIT_MASO))
L.adjustArousalLoss(3*power_multiplier)
descmessage += "And yet, it feels so good..!</span>" //I don't really understand masco, is this the right sort of thing they like?
E.enthrallTally += power_multiplier
E.resistanceTally -= power_multiplier
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='love'>I've let [E.enthrallGender] down...!</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='warning'>I've let [E.enthrallGender] down...</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='warning'>I've failed [E.master]...</b></span>"), 5)
E.resistanceTally += power_multiplier
E.enthrallTally += power_multiplier
E.cooldown += 1
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallscold", /datum/mood_event/enthrallscold, descmessage)
E.cooldown += 1
//teir 0
//SAY MY NAME works
if((findtext(message, saymyname_words)))
for(var/V in listeners)
var/mob/living/carbon/C = V
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall")
C.silent = 0
if(C.client?.prefs.lewdchem)
addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.enthrallGender]"), 5)
else
addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.master]"), 5)
//WAKE UP
else if((findtext(message, wakeup_words)))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
L.SetSleeping(0)//Can you hear while asleep?
switch(E.phase)
if(0)
E.phase = 3
E.status = null
user.emote("snap")
if(L.client?.prefs.lewdchem)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='big warning'>The snapping of your [E.enthrallGender]'s fingers brings you back to your enthralled state, obedient and ready to serve.</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='big warning'>The snapping of [E.master]'s fingers brings you back to being under their influence.</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You wake up [L]!</i></span>")
//tier 1
//PETSTATUS i.e. how they are
else if((findtext(message, petstatus_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
REMOVE_TRAIT(H, TRAIT_MUTE, "enthrall")
var/speaktrigger = ""
//phase
switch(E.phase)
if(0)
continue
if(1)
addtimer(CALLBACK(H, /atom/movable/proc/say, "I feel happy being with you."), 5)
continue
if(2)
speaktrigger += "[(H.client?.prefs.lewdchem?"I think I'm in love with you... ":"I find you really inspirational, ")]" //'
if(3)
speaktrigger += "[(H.client?.prefs.lewdchem?"I'm devoted to being your pet":"I'm commited to following your cause!")]! "
if(4)
speaktrigger += "[(H.client?.prefs.lewdchem?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!!
//mood
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
switch(mood.sanity)
if(SANITY_GREAT to INFINITY)
speaktrigger += "I'm beyond elated!! " //did you mean byond elated? hohoho
if(SANITY_NEUTRAL to SANITY_GREAT)
speaktrigger += "I'm really happy! "
if(SANITY_DISTURBED to SANITY_NEUTRAL)
speaktrigger += "I'm a little sad, "
if(SANITY_UNSTABLE to SANITY_DISTURBED)
speaktrigger += "I'm really upset, "
if(SANITY_CRAZY to SANITY_UNSTABLE)
speaktrigger += "I'm about to fall apart without you! "
if(SANITY_INSANE to SANITY_CRAZY)
speaktrigger += "Hold me, please.. "
//Withdrawal
switch(E.withdrawalTick)
if(10 to 36) //denial
speaktrigger += "I missed you, "
if(36 to 66) //barganing
speaktrigger += "I missed you, but I knew you'd come back for me! "
if(66 to 90) //anger
speaktrigger += "I couldn't take being away from you like that, "
if(90 to 140) //depression
speaktrigger += "I was so scared you'd never come back, "
if(140 to INFINITY) //acceptance
speaktrigger += "I'm hurt that you left me like that... I felt so alone... "
//hunger
switch(H.nutrition)
if(0 to NUTRITION_LEVEL_STARVING)
speaktrigger += "I'm famished, please feed me..! "
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
speaktrigger += "I'm so hungry... "
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
speaktrigger += "I'm hungry, "
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
speaktrigger += "I'm sated, "
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
speaktrigger += "I've a full belly! "
if(NUTRITION_LEVEL_FULL to INFINITY)
speaktrigger += "I'm fat... "
//health
switch(H.health)
if(100 to INFINITY)
speaktrigger += "I feel fit, "
if(80 to 99)
speaktrigger += "I ache a little bit, "
if(40 to 80)
speaktrigger += "I'm really hurt, "
if(0 to 40)
speaktrigger += "I'm in a lot of pain, help! "
if(-INFINITY to 0)
speaktrigger += "I'm barely concious and in so much pain, please help me! "
//toxin
switch(H.getToxLoss())
if(10 to 30)
speaktrigger += "I feel a bit queasy... "
if(30 to 60)
speaktrigger += "I feel nauseous... "
if(60 to INFINITY)
speaktrigger += "My head is pounding and I feel like I'm going to be sick... "
//oxygen
if (H.getOxyLoss() >= 25)
speaktrigger += "I can't breathe! "
//blind
if (HAS_TRAIT(H, TRAIT_BLIND))
speaktrigger += "I can't see! "
//deaf..?
if (HAS_TRAIT(H, TRAIT_DEAF))//How the heck you managed to get here I have no idea, but just in case!
speaktrigger += "I can barely hear you! "
//And the brain damage. And the brain damage. And the brain damage. And the brain damage. And the brain damage.
switch(H.getBrainLoss())
if(20 to 40)
speaktrigger += "I have a mild head ache, "
if(40 to 80)
speaktrigger += "I feel disorentated and confused, "
if(80 to 120)
speaktrigger += "My head feels like it's about to explode, "
if(120 to 160)
speaktrigger += "You are the only thing keeping my mind sane, "
if(160 to INFINITY)
speaktrigger += "I feel like I'm on the brink of losing my mind, "
//horny
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem)
switch(H.getArousalLoss())
if(40 to 60)
speaktrigger += "I'm feeling a little horny, "
if(60 to 80)
speaktrigger += "I'm feeling horny, "
if(80 to INFINITY)
speaktrigger += "I'm really, really horny, "
//collar
if(istype(H.wear_neck, /obj/item/clothing/neck/petcollar))
speaktrigger += "I love the collar you gave me, "
//End
if(H.client?.prefs.lewdchem)
speaktrigger += "[E.enthrallGender]!"
else
speaktrigger += "[user.first_name()]!"
//say it!
addtimer(CALLBACK(H, /atom/movable/proc/say, "[speaktrigger]"), 5)
E.cooldown += 1
//SILENCE
else if((findtext(message, silence_words)))
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
power_multiplier *= distancelist[get_dist(user, C)+1]
if (E.phase >= 3) //If target is fully enthralled,
ADD_TRAIT(C, TRAIT_MUTE, "enthrall")
else
C.silent += ((10 * power_multiplier) * E.phase)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>You are unable to speak!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You silence [C].</i></span>")
E.cooldown += 3
//SPEAK
else if((findtext(message, speak_words)))//fix
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall")
C.silent = 0
E.cooldown += 3
to_chat(user, "<span class='notice'><i>You [(C.client?.prefs.lewdchem?"allow [C] to speak again":"encourage [C] to speak again")].</i></span>")
//Antiresist
else if((findtext(message, antiresist_words)))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
E.status = "Antiresist"
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='big warning'>Your mind clouds over, as you find yourself unable to resist!</b></span>"), 5)
E.statusStrength = (1 * power_multiplier * E.phase)
E.cooldown += 15//Too short? yes, made 15
to_chat(user, "<span class='notice'><i>You frustrate [L]'s attempts at resisting.</i></span>")
//RESIST
else if((findtext(message, resist_words)))
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
power_multiplier *= distancelist[get_dist(user, C)+1]
E.deltaResist += (power_multiplier)
E.owner_resist()
E.cooldown += 2
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>You are spurred into resisting from [user]'s words!'</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You spark resistance in [C].</i></span>")
//FORGET (A way to cancel the process)
else if((findtext(message, forget_words)))
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 4)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='warning'>You're unable to forget about [(C.client?.prefs.lewdchem?"the dominating presence of [E.enthrallGender]":"[E.master]")]!</b></span>"), 5)
continue
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='warning'>You wake up, forgetting everything that just happened. You must've dozed off..? How embarassing!</b></span>"), 5)
C.Sleeping(50)
switch(E.phase)
if(1 to 2)
E.phase = -1
to_chat(C, "<span class='big warning'>You have no recollection of being enthralled by [E.master]!</b></span>")
to_chat(user, "<span class='notice'><i>You revert [C] back to their state before enthrallment.</i></span>")
if(3)
E.phase = 0
E.cooldown = 0
if(C.client?.prefs.lewdchem)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='big warning'>You revert to yourself before being enthralled by your [E.enthrallGender], with no memory of what happened.</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='big warning'>You revert to who you were before, with no memory of what happened with [E.master].</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You put [C] into a sleeper state, ready to turn them back at the snap of your fingers.</i></span>")
//ATTRACT
else if((findtext(message, attract_words)))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
L.throw_at(get_step_towards(user,L), 3 * power_multiplier, 1 * power_multiplier)
E.cooldown += 3
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You are drawn towards [user]!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You draw [L] towards you!</i></span>")
//teir 2
/* removed for now
//ORGASM
else if((findtext(message, orgasm_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase > 1)
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem) // probably a redundant check but for good measure
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='love'>Your [E.enthrallGender] pushes you over the limit, overwhelming your body with pleasure.</b></span>"), 5)
H.mob_climax(forced_climax=TRUE)
H.SetStun(20)
H.setArousalLoss(H.min_arousal)
E.resistanceTally = 0 //makes resistance 0, but resets arousal, resistance buildup is faster unaroused (massively so).
E.enthrallTally += power_multiplier
E.cooldown += 6
else
H.throw_at(get_step_towards(user,H), 3 * power_multiplier, 1 * power_multiplier)
*/
//awoo
else if((findtext(message, awoo_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
H.say("*awoo")
E.cooldown += 1
//Nya
else if((findtext(message, nya_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
playsound(get_turf(H), pick('sound/effects/meow1.ogg', 'modular_citadel/sound/voice/nya.ogg'), 50, 1, -1) //I'm very tempted to write a Fermis clause that makes them merowr.ogg if it's me. But, I also don't think snowflakism is okay. I would've gotten away for it too, if it wern't for my morals.
H.emote("me", 1, "lets out a nya!")
E.cooldown += 1
//SLEEP
else if((findtext(message, sleep_words)))
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
C.Sleeping(45 * power_multiplier)
E.cooldown += 10
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>Drowsiness suddenly overwhelms you as you fall asleep!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You send [C] to sleep.</i></span>")
//STRIP
else if((findtext(message, strip_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
var/items = H.get_contents()
for(var/obj/item/W in items)
if(W == H.wear_suit)
H.dropItemToGround(W, TRUE)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='[(H.client?.prefs.lewdchem?"love":"warning")]'>Before you can even think about it, you quickly remove your clothes in response to [(H.client?.prefs.lewdchem?"your [E.enthrallGender]'s command'":"[E.master]'s directive'")].</b></span>"), 5)
E.cooldown += 10
//WALK
else if((findtext(message, walk_words)))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
if(L.m_intent != MOVE_INTENT_WALK)
L.toggle_move_intent()
E.cooldown += 1
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You slow down to a walk.</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You encourage [L] to slow down.</i></span>")
//RUN
else if((findtext(message, run_words)))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
if(L.m_intent != MOVE_INTENT_RUN)
L.toggle_move_intent()
E.cooldown += 1
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You speed up into a jog!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You encourage [L] to pick up the pace!</i></span>")
//LIE DOWN
else if(findtext(message, liedown_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
L.lay_down()
E.cooldown += 10
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[(L.client?.prefs.lewdchem?"<span class='love'>You eagerly lie down!":"<span class='notice'>You suddenly lie down!")]</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You encourage [L] to lie down.</i></span>")
//KNOCKDOWN
else if(findtext(message, knockdown_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(2 to INFINITY)
L.Knockdown(30 * power_multiplier * E.phase)
E.cooldown += 8
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You suddenly drop to the ground!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You encourage [L] to drop down to the ground.</i></span>")
//tier3
//STATE TRIGGERS
else if((findtext(message, statecustom_words)))//doesn't work
for(var/V in listeners)
var/mob/living/carbon/C = V
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
if (E.phase == 3)
var/speaktrigger = ""
C.emote("me", 1, "whispers something quietly.")
if (get_dist(user, C) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to hear them!</b></span>")
continue
for (var/trigger in E.customTriggers)
speaktrigger += "[trigger], "
to_chat(user, "<b>[C]</b> whispers, \"<i>[speaktrigger] are my triggers.</i>\"")//So they don't trigger themselves!
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>You whisper your triggers to [(C.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")].</span>"), 5)
//CUSTOM TRIGGERS
else if((findtext(message, custom_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 3)
if (get_dist(user, H) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new trigger!</b></span>")
continue
else
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
user.SetStun(1000)//Hands are handy, so you have to stay still
H.SetStun(1000)
if (E.mental_capacity >= 5)
var/trigger = html_decode(stripped_input(user, "Enter the trigger phrase", MAX_MESSAGE_LEN))
var/custom_words_words_list = list("Speak", "Echo", "Shock", "Cum", "Kneel", "Strip", "Trance", "Cancel")
var/trigger2 = input(user, "Pick an effect", "Effects") in custom_words_words_list
trigger2 = lowertext(trigger2)
if ((findtext(trigger2, custom_words_words)))
if (trigger2 == "speak" || trigger2 == "echo")
var/trigger3 = html_decode(stripped_input(user, "Enter the phrase spoken. Abusing this to self antag is bannable.", MAX_MESSAGE_LEN))
E.customTriggers[trigger] = list(trigger2, trigger3)
log_game("FERMICHEM: [H] has been implanted by [user] with [trigger], triggering [trigger2], to send [trigger3].")
if(findtext(trigger3, "admin"))
message_admins("FERMICHEM: [user] maybe be trying to abuse MKUltra by implanting by [H] with [trigger], triggering [trigger2], to send [trigger3].")
else
E.customTriggers[trigger] = trigger2
log_game("FERMICHEM: [H] has been implanted by [user] with [trigger], triggering [trigger2].")
E.mental_capacity -= 5
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(H.client?.prefs.lewdchem?"your [E.enthrallGender]":"[E.master]")] whispers you a new trigger.</span>"), 5)
to_chat(user, "<span class='notice'><i>You sucessfully set the trigger word [trigger] in [H]</i></span>")
else
to_chat(user, "<span class='warning'>Your pet looks at you confused, it seems they don't understand that effect!</b></span>")
else
to_chat(user, "<span class='warning'>Your pet looks at you with a vacant blase expression, you don't think you can program anything else into them</b></span>")
user.SetStun(0)
H.SetStun(0)
//CUSTOM ECHO
else if((findtext(message, custom_echo)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 3)
if (get_dist(user, H) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new echophrase!</b></span>")
continue
else
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
user.SetStun(1000)//Hands are handy, so you have to stay still
H.SetStun(1000)
var/trigger = stripped_input(user, "Enter the loop phrase", MAX_MESSAGE_LEN)
var/customSpan = list("Notice", "Warning", "Hypnophrase", "Love", "Velvet")
var/trigger2 = input(user, "Pick the style", "Style") in customSpan
trigger2 = lowertext(trigger2)
E.customEcho = trigger
E.customSpan = trigger2
user.SetStun(0)
H.SetStun(0)
to_chat(user, "<span class='notice'><i>You sucessfully set an echoing phrase in [H]</i></span>")
//CUSTOM OBJECTIVE
else if((findtext(message, objective_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 3)
if (get_dist(user, H) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new objective!</b></span>")
continue
else
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'")
user.SetStun(1000)//So you can't run away!
H.SetStun(1000)
if (E.mental_capacity >= 200)
var/datum/objective/brainwashing/objective = stripped_input(user, "Add an objective to give your pet.", MAX_MESSAGE_LEN)
if(!LAZYLEN(objective))
to_chat(user, "<span class='warning'>You can't give your pet an objective to do nothing!</b></span>")
continue
//Pets don't understand harm
objective = replacetext(lowertext(objective), "kill", "hug")
objective = replacetext(lowertext(objective), "murder", "cuddle")
objective = replacetext(lowertext(objective), "harm", "snuggle")
objective = replacetext(lowertext(objective), "decapitate", "headpat")
objective = replacetext(lowertext(objective), "strangle", "meow at")
objective = replacetext(lowertext(objective), "suicide", "self-love")
message_admins("[H] has been implanted by [user] with the objective [objective].")
log_game("FERMICHEM: [H] has been implanted by [user] with the objective [objective] via MKUltra.")
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(H.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")] whispers you a new objective.</span>"), 5)
brainwash(H, objective)
E.mental_capacity -= 200
to_chat(user, "<span class='notice'><i>You sucessfully give an objective to [H]</i></span>")
else
to_chat(user, "<span class='warning'>Your pet looks at you with a vacant blasé expression, you don't think you can program anything else into them</b></span>")
user.SetStun(0)
H.SetStun(0)
//INSTILL
else if((findtext(message, instill_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 3 && H.client?.prefs.lewdchem)
var/instill = stripped_input(user, "Instill an emotion in your [(user.client?.prefs.lewdchem?"Your pet":"listener")].", MAX_MESSAGE_LEN)
to_chat(H, "<i>[instill]</i>")
to_chat(user, "<span class='notice'><i>You sucessfully instill a feeling in [H]</i></span>")
log_game("FERMICHEM: [H] has been instilled by [user] with [instill] via MKUltra.")
E.cooldown += 1
//RECOGNISE
else if((findtext(message, recognise_words)))
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase > 1)
if(user.ckey == E.enthrallID && user.real_name == E.master.real_name)
E.master = user
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='nicegreen'>[(H.client?.prefs.lewdchem?"You hear the words of your [E.enthrallGender] again!! They're back!!":"You recognise the voice of [E.master].")]</b></span>"), 5)
to_chat(user, "<span class='notice'><i>[H] looks at you with sparkling eyes, recognising you!</i></span>")
//I dunno how to do state objectives without them revealing they're an antag
//HEAL (maybe make this nap instead?)
else if(findtext(message, heal_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3)//Tier 3 only
E.status = "heal"
E.statusStrength = (5 * power_multiplier)
E.cooldown += 5
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You begin to lick your wounds.</b></span>"), 5)
L.Stun(15 * power_multiplier)
to_chat(user, "<span class='notice'><i>[L] begins to lick their wounds.</i></span>")
//STUN
else if(findtext(message, stun_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3 to INFINITY)
L.Stun(40 * power_multiplier)
E.cooldown += 8
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>Your muscles freeze up!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You cause [L] to freeze up!</i></span>")
//HALLUCINATE
else if(findtext(message, hallucinate_words))
for(var/V in listeners)
var/mob/living/carbon/C = V
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3 to INFINITY)
new /datum/hallucination/delusion(C, TRUE, null,150 * power_multiplier,0)
to_chat(user, "<span class='notice'><i>You send [C] on a trip.</i></span>")
//HOT
else if(findtext(message, hot_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3 to INFINITY)
L.adjust_bodytemperature(50 * power_multiplier)//This seems nuts, reduced it, but then it didn't do anything, so I reverted it.
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You feel your metabolism speed up!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You speed [L]'s metabolism up!</i></span>")
//COLD
else if(findtext(message, cold_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3 to INFINITY)
L.adjust_bodytemperature(-50 * power_multiplier)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You feel your metabolism slow down!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You slow [L]'s metabolism down!</i></span>")
//GET UP
else if(findtext(message, getup_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3 to INFINITY)//Tier 3 only
if(L.resting)
L.lay_down() //aka get up
L.SetStun(0)
L.SetKnockdown(0)
L.SetUnconscious(0) //i said get up i don't care if you're being tased
E.cooldown += 10 //This could be really strong
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You jump to your feet from sheer willpower!</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You spur [L] to their feet!</i></span>")
//PACIFY
else if(findtext(message, pacify_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3)//Tier 3 only
E.status = "pacify"
E.cooldown += 10
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You feel like never hurting anyone ever again.</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You remove any intent to harm from [L]'s mind.</i></span>")
//CHARGE
else if(findtext(message, charge_words))
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
switch(E.phase)
if(3)//Tier 3 only
E.statusStrength = 2* power_multiplier
E.status = "charge"
E.cooldown += 10
to_chat(user, "<span class='notice'><i>You rally [L], leading them into a charge!</i></span>")
if(message_admins || debug)//Do you want this in?
message_admins("[ADMIN_LOOKUPFLW(user)] has said '[log_message]' with a Velvet Voice, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
log_game("FERMICHEM: [key_name(user)] ckey: [user.key] has said '[log_message]' with a Velvet Voice, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have spoken with a velvet voice")
//SSblackbox.record_feedback("tally", "Velvet_voice", 1, log_message) If this is on, it fills the thing up and OOFs the server
return
#undef COOLDOWN_STUN
#undef COOLDOWN_DAMAGE
+1 -1
View File
@@ -1325,7 +1325,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer."
item = /obj/item/emagrecharge
cost = 2
/datum/uplink_item/device_tools/cutouts
name = "Adaptive Cardboard Cutouts"
desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \
+3 -1
View File
@@ -28,7 +28,9 @@
contraband = list(/obj/item/reagent_containers/pill/tox = 3,
/obj/item/reagent_containers/pill/morphine = 4,
/obj/item/reagent_containers/pill/charcoal = 6)
premium = list(/obj/item/storage/box/hug/medical = 1,
premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2,
/obj/item/storage/box/hug/medical = 1,
/obj/item/storage/pill_bottle/psicodine = 2,
/obj/item/reagent_containers/hypospray/medipen = 3,
/obj/item/storage/belt/medical = 3,
/obj/item/wrench/medical = 1,
+2 -1
View File
@@ -338,7 +338,8 @@
/obj/item/clothing/suit/toggle/labcoat/chemist = 3,
/obj/item/storage/backpack/chemistry = 3,
/obj/item/storage/backpack/satchel/chem = 3,
/obj/item/storage/bag/chemistry = 3)
/obj/item/storage/bag/chemistry = 3,
/obj/item/fermichem/pHbooklet = 3)//pH indicator)
refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe
/obj/item/vending_refill/wardrobe/chem_wardrobe