Merge pull request #9 from Thalpy/FermiChem

Fermi chem update - does not compile mid fix!
This commit is contained in:
Thalpy
2019-05-11 14:15:13 +01:00
committed by GitHub
29 changed files with 3064 additions and 1055 deletions
+1
View File
@@ -122,3 +122,4 @@
#define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun"
#define ORGAN_SLOT_TAIL "tail"
#define ORGAN_SLOT_PENIS "penis"
#define ORGAN_SLOT_BREASTS "breasts"
+4
View File
@@ -137,6 +137,9 @@
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
#define COMSIG_LIVING_SAY "say" //mob/living/say() - return COMSIG_I_FORGET_WHAT_TO_CALL_IT to interrupt before message sent.
#define COMPONENT_NO_SAY 1 // Here I am pretending to know what I'm doing.
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
@@ -145,6 +148,7 @@
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
#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)
@@ -109,5 +109,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/reagent_containers/pill/floorpill = 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,
"" = 3
))
@@ -0,0 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(chemistry)
wait = 5
flags = SS_KEEP_TIMING
+4 -2
View File
@@ -15,7 +15,7 @@
/datum/component/mood/Initialize()
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
START_PROCESSING(SSmood, src)
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
@@ -118,6 +118,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]"
@@ -160,7 +162,7 @@
clear_event(null, "depression")
holdmyinsanityeffect = insanity_effect
HandleNutrition(owner)
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
+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 = 50
/datum/mood_event/happiness_drug_good_od
description = "<span class='nicegreen'>YES! YES!! YES!!!</span>\n"
mood_change = 100
timeout = 300
special_screen_obj = "mood_happiness_good"
/datum/mood_event/happiness_drug_bad_od
description = "<span class='boldwarning'>NO! NO!! NO!!!</span>\n"
mood_change = -100
timeout = 300
special_screen_obj = "mood_happiness_bad"
+330 -322
View File
@@ -1,322 +1,330 @@
/* 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)
/* 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 = "Made by Fermichem - They have a little picture of Doctor Ronald Hyatt with a giant dong on them. The warming states not to take more than 10u at a time."
/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)
+168 -328
View File
@@ -53,10 +53,6 @@
var/addiction_tick = 1
var/list/datum/reagent/addiction_list = new/list()
var/reagents_holder_flags
var/targetVol = 0
var/reactedVol = 0
var/fermiIsReacting = FALSE
var/fermiReactID = null
/datum/reagents/New(maximum=100)
maximum_volume = maximum
@@ -341,361 +337,205 @@
R.on_update (A)
update_total()
/datum/reagents/proc/handle_reactions()//HERE EDIT HERE THE MAIN REACTION FERMICHEMS ASSEMBLE! I hope rp is similar
if(fermiIsReacting == TRUE)
//reagents_holder_flags |= REAGENT_NOREACT unsure if this is needed
return
var/list/cached_reagents = reagent_list //a list of the reagents?
var/list/cached_reactions = GLOB.chemical_reactions_list //a list of the whole reactions?
var/datum/cached_my_atom = my_atom //It says my atom, but I didn't bring one with me!!
if(reagents_holder_flags & REAGENT_NOREACT) //Not sure on reagents_holder_flags, but I think it checks to see if theres a reaction with current stuff.
return //Yup, no reactions here. No siree.
/datum/reagents/process()
var/occured = handle_reactions(TRUE)
if(!occured)
return PROCESS_KILL
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.
//if(fermiIsReacting == TRUE)
/* if (reactedVol >= targetVol && targetVol != 0)
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
message_admins("FermiChem processing stopped in reaction handler")
reaction_occurred = 1
return
else
message_admins("FermiChem processing passed in reaction handler")
return
*/
do //What does do do in byond? It sounds very redundant? is it a while loop?
var/list/possible_reactions = list() //init list
reaction_occurred = 0 // sets it back to 0?
for(var/reagent in cached_reagents) //for reagent in beaker/holder
var/datum/reagent/R = reagent //check to make sure that reagent is there for the reaction list
for(var/reaction in cached_reactions[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
/datum/reagents/proc/handle_reactions(fermi_chem_react = FALSE)//HERE EDIT HERE THE MAIN REACTION FERMICHEMS ASSEMBLE! I hope rp is similar
return
if(reagents_holder_flags & REAGENT_NOREACT)
return //don't react
//cache things for performance
var/list/cached_reagents = reagent_list
var/list/cached_reactions = GLOB.chemical_reactions_list
var/datum/cached_my_atom = my_atom
var/reaction_occurred //if a reaction happened
var/list/fermichem_reacted //keeps track of fermichem reactions that already reacted to prevent it from being instant
do
var/list/possible_reactions
reaction_occurred = FALSE
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
for(var/reaction in cached_reactions[R.id])
if(!reaction)
continue
var/datum/chemical_reaction/C = reaction
var/list/cached_required_reagents = C.required_reagents
var/total_required_reagents = cached_required_reagents.len
var/total_matching_reagents = 0
var/list/cached_required_catalysts = C.required_catalysts
var/total_required_catalysts = cached_required_catalysts.len
var/total_matching_catalysts= 0
var/matching_container = 0
var/matching_other = 0
var/required_temp = C.required_temp
var/is_cold_recipe = C.is_cold_recipe
var/meets_temp_requirement = 0
var/has_special_react = C.special_react
var/can_special_react = 0
var/fail = FALSE
for(var/B in cached_required_reagents)
if(!has_reagent(B, cached_required_reagents[B]))
fail = TRUE
break
total_matching_reagents++
if(fail)
continue
for(var/B in cached_required_catalysts)
if(!has_reagent(B, cached_required_catalysts[B]))
fail = TRUE
break
total_matching_catalysts++
if(fail)
continue
if(cached_my_atom)
if(!C.required_container)
matching_container = 1
else
if(cached_my_atom.type == C.required_container)//if the suspected container is a container
matching_container = 1
if(C.required_container && C.required_container != cached_my_atom.type)
continue
if (isliving(cached_my_atom) && !C.mob_react) //Makes it so certain chemical reactions don't occur in mobs
return
if(!C.required_other)//Checks for other things required
matching_other = 1//binary check passes
else if(istype(cached_my_atom, /obj/item/slime_extract))//if the object is a slime_extract. This might be complicated as to not break them via fermichem
var/obj/item/slime_extract/M = cached_my_atom
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
matching_other = 1
continue
if(C.required_other) //Checks for other things required
if(istype(cached_my_atom, /obj/item/slime_extract))//if the object is a slime_extract. This might be complicated as to not break them via fermichem
var/obj/item/slime_extract/M = cached_my_atom
if(M.Uses <= 0) // added a limit to slime cores -- Muskets requested this
continue
else
if(!C.required_container)//I'm not sure why this is here twice, I think if it's not a beaker? Oh, cyro.
matching_container = 1
if(!C.required_other)
matching_other = 1
//FermiChem
/*
if (chem_temp > C.ExplodeTemp)//Check to see if reaction is too hot!
if (C.FermiExplode == TRUE)
//To be added!
else
FermiExplode()
//explode function!!
*/
if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))//Temperature check!!
meets_temp_requirement = 1//binary pass
if(!has_special_react || C.check_special_react(src))
can_special_react = 1
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && meets_temp_requirement && can_special_react)
possible_reactions += C
if(possible_reactions.len)//does list exist?
if(C.required_container || C.required_other)
continue
if(required_temp && (is_cold_recipe? (chem_temp > required_temp) : (chem_temp < required_temp)))
continue
if(has_special_react && !C.check_special_react(src))
continue
if(C.FermiChem) //fermichem checks
if(chem_temp < C.OptimalTempMin) //too low temperature
continue
if(LAZYACCESS(fermichem_reacted, C)) //fermichems don't keep reacting instantly
continue
START_PROCESSING(SSchemistry, src) //start processing
if(!fermi_chem_react) //only react fermichems on process icks
continue
LAZYADD(possible_reactions, C)
if(length(possible_reactions)) //does list exist?
var/datum/chemical_reaction/selected_reaction = possible_reactions[1]
//select the reaction with the most extreme temperature requirements
for(var/V in possible_reactions)//why V, surely that would indicate volume? V is the reaction potential.
var/datum/chemical_reaction/competitor = V //competitor? I think this is theres two of them. Troubling..!
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(competitor.required_temp <= selected_reaction.required_temp)//only returns with lower if reaction "is cold" var.
selected_reaction = competitor
else
if(competitor.required_temp >= selected_reaction.required_temp) //will return with the hotter reacting first.
selected_reaction = competitor
for(var/I in possible_reactions)
var/datum/chemical_reaction/competitor = I
if(selected_reaction.is_cold_recipe? competitor.required_temp < selected_reaction.required_temp : competitor.required_temp > selected_reaction.required_temp)
selected_reaction = competitor
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 //Wat
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B]))//a simple one over the other? (Is this for multiplying end product? Useful for toxinsludge buildup)
var/special_react_result = selected_reaction.special_react
//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.
//BRANCH HERE
//if(selected_reaction)
var/datum/chemical_reaction/C = selected_reaction
if (C.FermiChem == TRUE && !continue_reacting)
message_admins("FermiChem Proc'd")
for(var/P in selected_reaction.results)
targetVol = cached_results[P]*multiplier
message_admins("FermiChem target volume: [targetVol]")
if (chem_temp > C.OptimalTempMin)//To prevent pointless reactions
//if (reactedVol < targetVol)
if (fermiIsReacting == TRUE)
return 0
else
//reactedVol = FermiReact(selected_reaction, chem_temp, pH, multiplier, reactedVol, targetVol, cached_required_reagents, cached_results)
START_PROCESSING(SSprocessing, src)
message_admins("FermiChem processing started")
fermiIsReacting = TRUE
fermiReactID = selected_reaction
reaction_occurred = 1
//else
// fermiIsReacting = FALSE
// STOP_PROCESSING(SSfastprocess, src)
else
return 0
SSblackbox.record_feedback("tally", "Fermi_chemical_reaction", reactedVol, C.id)//log
//Standard reaction mechanics:
else
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B]))//a simple one over the other? (Is this for multiplying end product? Useful for toxinsludge buildup)
var/multiplier = INFINITY //the multiplier of the stnadard "1 reaction" we managed to do this cycle
if(!selected_reaction.FermiChem) //it's a normal ss13 chem reaction, instant reactions.
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1)//safety? removes reagents from beaker using remove function.
for(var/P in selected_reaction.results)//Not sure how this works, what is selected_reaction.results?
multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B])) //cap by the multiplier of the required you can get out of this
//remove reactants
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = TRUE)
//add products
for(var/P in cached_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)//add reagent function!! I THINK I can do this:
SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P] * multiplier, P)
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
else //FermiiiCheeeem!
//FERMICHEM BEGIN
//--CHECKS
message_admins("FermiChem Proc'd")
var/target_volume = 0
for(var/result_id in cached_results)
target_volume += multiplier * cached_results[result_id]
message_admins("FermiChem target volume: [target_volume]")
//--PROCESS
message_admins("FermiChem processing started")
//--REACTION
//set up fermichem variables
var/deltaT = 0
var/deltapH = 0
var/stepChemAmount = 0
var/purity = 1
//For now, purity is handled elsewhere
//check extremes first
if(chem_temp > selected_reaction.ExplodeTemp)
FermiExplode(selected_reaction)
else if(!ISINRANGE(pH, 0, 14))
//Create chemical sludge eventually(for now just destroy the beaker I guess?)
//TODO Strong acids eat glass, make it so you NEED plastic beakers for superacids(for some reactions)
FermiExplode()
//Calculate DeltaT (Deviation of T from optimal)
if (chem_temp < selected_reaction.OptimalTempMax && chem_temp >= selected_reaction.OptimalTempMin)
deltaT = (((selected_reaction.OptimalTempMin - chem_temp)**selected_reaction.CurveSharpT)/((selected_reaction.OptimalTempMax - selected_reaction.OptimalTempMin)**selected_reaction.CurveSharpT))
else if (chem_temp >= selected_reaction.OptimalTempMax)
deltaT = 1
else
deltaT = 0
message_admins("calculating temperature factor, min: [selected_reaction.OptimalTempMin], max: [selected_reaction.OptimalTempMax], Exponential: [selected_reaction.CurveSharpT], deltaT: [deltaT]")
//Calculate DeltapH (Deviation of pH from optimal)
//Lower range
if (pH < selected_reaction.OptimalpHMin)
if (pH < (selected_reaction.OptimalpHMin - selected_reaction.ReactpHLim))
deltapH = 0
else
deltapH = (((pH - (selected_reaction.OptimalpHMin - selected_reaction.ReactpHLim))**selected_reaction.CurveSharppH)/(selected_reaction.ReactpHLim**selected_reaction.CurveSharppH))
//Upper range
else if (pH > selected_reaction.OptimalpHMin)
if (pH > (selected_reaction.OptimalpHMin + selected_reaction.ReactpHLim))
deltapH = 0
else
deltapH = ((selected_reaction.ReactpHLim -(pH - (selected_reaction.OptimalpHMax + selected_reaction.ReactpHLim))+selected_reaction.ReactpHLim)/(selected_reaction.ReactpHLim**selected_reaction.CurveSharppH))
//Within mid range
else if (pH >= selected_reaction.OptimalpHMin && pH <= selected_reaction.OptimalpHMax)
deltapH = 1
//This should never proc:
else
message_admins("Fermichem's pH broke!! Please let Fermis know!!")
WARNING("[my_atom] attempted to determine FermiChem pH for '[selected_reaction.id]' which broke for some reason! ([usr])")
//TODO Add CatalystFact
message_admins("calculating pH factor(purity), pH: [pH], min: [selected_reaction.OptimalpHMin]-[selected_reaction.ReactpHLim], max: [selected_reaction.OptimalpHMax]+[selected_reaction.ReactpHLim], deltapH: [deltapH]")
stepChemAmount = target_volume * deltaT
if (stepChemAmount > selected_reaction.RateUpLim)
stepChemAmount = selected_reaction.RateUpLim
else if (stepChemAmount <= 0.01)
message_admins("stepChem underflow [stepChemAmount]")
stepChemAmount = 0.02
purity = deltapH
message_admins("cached_results: [cached_results], stepChemAmount [stepChemAmount]")
if(stepChemAmount > multiplier) //too much
message_admins("stepChemAmount was over multiplier for some reason..?")
for(var/B in cached_required_reagents)
message_admins("cached_required_reagents(B): [cached_required_reagents[B]], base stepChemAmount [stepChemAmount]")
remove_reagent(B, (stepChemAmount * cached_required_reagents[B]), safety = TRUE)//safety? removes reagents from beaker using remove function.
for(var/P in cached_results)//Not sure how this works, what is selected_reaction.results?
//reactedVol = max(reactedVol, 1) //this shouldnt happen ...
SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*stepChemAmount, P)//log
add_reagent(P, cached_results[P] * stepChemAmount, null, chem_temp)//add reagent function!! I THINK I can do this:
message_admins("purity: [purity], purity of beaker")
message_admins("Temp before change: [chem_temp], pH after change: [pH]")
//Apply pH changes and thermal output of reaction to beaker
chem_temp += (selected_reaction.ThermicConstant * stepChemAmount)
pH += (selected_reaction.HIonRelease * stepChemAmount)
message_admins("Temp after change: [chem_temp], pH after change: [pH]")
SSblackbox.record_feedback("tally", "Fermi_chemical_reaction", multiplier, selected_reaction.id)//log
//ensure the same thing doesn't happen in the same tick
LAZYSET(fermichem_reacted, selected_reaction, TRUE)
//FERMICHEM END
//reaction is done, do the effects.
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)
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)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] [selected_reaction.mix_message]</span>")
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] [selected_reaction.mix_message]</span>")
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)//while do nothing?
update_total()//Don't know waht this does.
return 0//end!
/datum/reagents/process()
var/datum/chemical_reaction/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
message_admins("updating targetVol from [targetVol]")
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round(get_reagent_amount(B) / cached_required_reagents[B]))
if (multiplier == 0)
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
message_admins("FermiChem STOPPED due to reactant removal! Reacted vol: [reactedVol] of [targetVol]")
reactedVol = 0
targetVol = 0
handle_reactions()
update_total()
return
for(var/P in cached_results)
targetVol = cached_results[P]*multiplier
message_admins("to [targetVol]")
if (fermiIsReacting == FALSE)
message_admins("THIS SHOULD NEVER APPEAR!")
if (chem_temp > C.OptimalTempMin && fermiIsReacting == TRUE)//To prevent pointless reactions
if (reactedVol < targetVol)
reactedVol = FermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results)
message_admins("FermiChem tick activated started, Reacted vol: [reactedVol] of [targetVol]")
else
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
message_admins("FermiChem STOPPED due to volume reached! Reacted vol: [reactedVol] of [targetVol]")
reactedVol = 0
targetVol = 0
handle_reactions()
update_total()
return
else
STOP_PROCESSING(SSprocessing, src)
message_admins("FermiChem STOPPED due to temperature! Reacted vol: [reactedVol] of [targetVol]")
fermiIsReacting = FALSE
reactedVol = 0
targetVol = 0
handle_reactions()
update_total()
return
//handle_reactions()
/datum/reagents/proc/FermiReact(selected_reaction, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results)
var/datum/chemical_reaction/C = selected_reaction
var/deltaT = 0
var/deltapH = 0
var/stepChemAmmount = 0
//var/ammoReacted = 0
//get purity from combined beaker reactant purities HERE.
var/purity = 1
//var/tempVol = totalVol
message_admins("Loop beginning")
//Begin Parse
//Check extremes first
if (chem_temp > C.ExplodeTemp)
//go to explode proc
message_admins("temperature is over limit: [C.ExplodeTemp] Current temperature: [chem_temp]")
FermiExplode()
if (pH > 14 || pH < 0)
//Create chemical sludge eventually(for now just destroy the beaker I guess?)
//TODO Strong acids eat glass, make it so you NEED plastic beakers for superacids(for some reactions)
message_admins("pH is lover limit, cur pH: [pH]")
FermiExplode()
//For now, purity is handled elsewhere
//Calculate DeltaT (Deviation of T from optimal)
if (chem_temp < C.OptimalTempMax && chem_temp >= C.OptimalTempMin)
deltaT = (((C.OptimalTempMin - chem_temp)**C.CurveSharpT)/((C.OptimalTempMax - C.OptimalTempMin)**C.CurveSharpT))
else if (chem_temp >= C.OptimalTempMax)
deltaT = 1
else
deltaT = 0
message_admins("calculating temperature factor, min: [C.OptimalTempMin], max: [C.OptimalTempMax], Exponential: [C.CurveSharpT], deltaT: [deltaT]")
//Calculate DeltapH (Deviation of pH from optimal)
//Lower range
if (pH < C.OptimalpHMin)
if (pH < (C.OptimalpHMin - C.ReactpHLim))
deltapH = 0
else
deltapH = (((pH - (C.OptimalpHMin - C.ReactpHLim))**C.CurveSharppH)/(C.ReactpHLim**C.CurveSharppH))
//Upper range
else if (pH > C.OptimalpHMin)
if (pH > (C.OptimalpHMin + C.ReactpHLim))
deltapH = 0
else
deltapH = ((C.ReactpHLim -(pH - (C.OptimalpHMax + C.ReactpHLim))+C.ReactpHLim)/(C.ReactpHLim**C.CurveSharppH))
//Within mid range
else if (pH >= C.OptimalpHMin && pH <= C.OptimalpHMax)
deltapH = 1
//This should never proc:
else
message_admins("Fermichem's pH broke!! Please let Fermis know!!")
WARNING("[my_atom] attempted to determine FermiChem pH for '[C.id]' which broke for some reason! ([usr])")
//TODO Add CatalystFact
message_admins("calculating pH factor(purity), pH: [pH], min: [C.OptimalpHMin]-[C.ReactpHLim], max: [C.OptimalpHMax]+[C.ReactpHLim], deltapH: [deltapH]")
stepChemAmmount = targetVol * deltaT
if (stepChemAmmount > C.RateUpLim)
stepChemAmmount = C.RateUpLim
else if (stepChemAmmount <= 0.01)
message_admins("stepChem underflow [stepChemAmmount]")
stepChemAmmount = 0.02
if ((reactedVol + stepChemAmmount) > targetVol)
stepChemAmmount = targetVol - reactedVol
message_admins("target volume reached. Reaction should stop after this loop. stepChemAmmount: [stepChemAmmount] + reactedVol: [reactedVol] = targetVol [targetVol]")
if (reactedVol > 0)
purity = ((purity * reactedVol) + (deltapH * stepChemAmmount)) /((reactedVol+ stepChemAmmount)) //This should add the purity to the product
else
purity = deltapH
// End.
/*
for(var/B in cached_required_reagents) //
tempVol = min(reactedVol, round(get_reagent_amount(B) / cached_required_reagents[B]))//a simple one over the other? (Is this for multiplying end product? Useful for toxinsludge buildup)
*/
message_admins("cached_results: [cached_results], reactedVol: [reactedVol], stepChemAmmount [stepChemAmmount]")
for(var/B in cached_required_reagents)
message_admins("cached_required_reagents(B): [cached_required_reagents[B]], reactedVol: [reactedVol], base stepChemAmmount [stepChemAmmount]")
remove_reagent(B, (stepChemAmmount * cached_required_reagents[B]), safety = 1)//safety? removes reagents from beaker using remove function.
for(var/P in cached_results)//Not sure how this works, what is selected_reaction.results?
//reactedVol = max(reactedVol, 1) //this shouldnt happen ...
SSblackbox.record_feedback("tally", "chemical_reaction", cached_results[P]*stepChemAmmount, P)//log
add_reagent(P, cached_results[P]*stepChemAmmount, null, chem_temp)//add reagent function!! I THINK I can do this:
message_admins("purity: [purity], purity of beaker")
message_admins("Temp before change: [chem_temp], pH after change: [pH]")
//Apply pH changes and thermal output of reaction to beaker
chem_temp += (C.ThermicConstant * stepChemAmmount)
pH += (C.HIonRelease * stepChemAmmount)
message_admins("Temp after change: [chem_temp], pH after change: [pH]")
reactedVol = reactedVol + stepChemAmmount
return (reactedVol)
/datum/reagents/proc/FermiExplode()
return
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 = TRUE
while(reaction_occurred)
update_total()
return reaction_occurred
/datum/reagents/proc/isolate_reagent(reagent)
var/list/cached_reagents = reagent_list
@@ -130,3 +130,7 @@
rs += "[R.name], [R.volume]"
return rs.Join(" | ")
//Handler for explosion reaction
/datum/reagents/proc/FermiExplode(turf/T, obj/O, mob/living/M, volume)
return
@@ -359,6 +359,83 @@
..()
. = 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
/datum/reagent/drug/happiness/on_mob_add(mob/living/L)
..()
L.add_trait(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)
L.remove_trait(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"
@@ -429,4 +506,3 @@
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
@@ -60,6 +60,9 @@
M.SetSleeping(0, 0)
M.jitteriness = 0
M.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
if(M.blood_volume < BLOOD_VOLUME_NORMAL)
M.blood_volume = BLOOD_VOLUME_NORMAL
for(var/thing in M.diseases)
var/datum/disease/D = thing
if(D.severity == DISEASE_SEVERITY_POSITIVE)
@@ -1296,3 +1299,37 @@
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
/datum/reagent/medicine/psicodine/on_mob_add(mob/living/L)
..()
L.add_trait(TRAIT_FEARLESS, id)
/datum/reagent/medicine/psicodine/on_mob_delete(mob/living/L)
L.remove_trait(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
@@ -35,6 +35,9 @@
var/FermiChem = FALSE //If the chemical uses the Fermichem reaction mechanics
var/FermiExplode = FALSE //If the chemical explodes in a special way as a result of
var/ImpureChem = "toxin" //What chemical is produced with an inpure reaction
var/InverseChemVal = 0.3
var/InverseChem = "toxin"
/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume, specialreact)
return
@@ -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"
@@ -172,6 +172,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"
@@ -252,3 +258,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"
+243 -239
View File
@@ -1,239 +1,243 @@
/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>")
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>")
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("PEenlager" = 10)
/obj/item/reagent_containers/pill/breast_enlargement
name = "breast enlargement pill"
list_reagents = list("BEenlager" = 10)
+22
View File
@@ -196,3 +196,25 @@
/obj/item/organ/tongue/robot/get_spans()
return ..() | SPAN_ROBOT
//FermiChem
/obj/item/organ/tongue/OwO
name = "fluffy tongue"
desc = "OwO what's this?"
icon_state = "tonguenormal"
taste_sensitivity = 10 // extra sensitive and inquisitive uwu
/obj/item/organ/tongue/OwO/TongueSpeech(var/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, "th", "ff") //too incoherent in practice
message = replacetext(message, "l", "w")
message = replacetext(message, "r", "w")
if(prob(20))
message += pick(" OwO", " uwu")
message = lowertext(message)
return message
+690
View File
@@ -608,6 +608,696 @@
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 = "voice_of_god"
actions_types = list(/datum/action/item_action/organ_action/colossus)
var/next_command = 0
var/cooldown_mod = 1
var/base_multiplier = 1
spans = list("say","yell")
/*
/datum/action/item_action/organ_action/colossus
name = "Voice of God"
var/obj/item/organ/vocal_cords/colossus/cords = null
/datum/action/item_action/organ_action/colossus/New()
..()
cords = target
/datum/action/item_action/organ_action/colossus/IsAvailable()
if(world.time < cords.next_command)
return FALSE
if(!owner)
return FALSE
if(!owner.can_speak())
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return FALSE
return TRUE
/datum/action/item_action/organ_action/colossus/Trigger()
. = ..()
if(!IsAvailable())
if(world.time < cords.next_command)
to_chat(owner, "<span class='notice'>You must wait [DisplayTimeText(cords.next_command - world.time)] before Speaking again.</span>")
return
var/command = input(owner, "Speak with the Voice of God", "Command")
if(QDELETED(src) || QDELETED(owner))
return
if(!command)
return
owner.say(".x[command]")
/obj/item/organ/vocal_cords/colossus/can_speak_with()
if(world.time < next_command)
to_chat(owner, "<span class='notice'>You must wait [DisplayTimeText(next_command - world.time)] before Speaking again.</span>")
return FALSE
if(!owner)
return FALSE
if(!owner.can_speak())
to_chat(owner, "<span class='warning'>You are unable to speak!</span>")
return FALSE
return TRUE
*/
/obj/item/organ/vocal_cords/velvet/handle_speech(message)
velvetspeech(message, owner, spans, base_multiplier)
return //velvetspeech should handle speech
/obj/item/organ/vocal_cords/velvet/speak_with(message)
velvetspeech(message, owner, spans, base_multiplier)
//next_command = world.time + (cooldown * cooldown_mod)
//////////////////////////////////////
///////////FermiChem//////////////////
//////////////////////////////////////
/proc/velvetspeech(message, mob/living/user, list/span_list, base_multiplier = 1, include_speaker = FALSE, message_admins = TRUE)
var/cooldown = 0
if(!user || !user.can_speak() || user.stat)
return 0 //no cooldown
var/log_message = message
if(!span_list || !span_list.len) //Not too sure what this does, I think it changes your output message depending if you're a cultist or not? I.e. font
if(iscultist(user))
span_list = list("narsiesmall")
else if (is_servant_of_ratvar(user))
span_list = list("ratvar")
else
span_list = list()
user.say(message, sanitize = TRUE)//Removed spans = span_list, It should just augment normal speech
//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
if(L == user && !include_speaker)
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
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
if (E.cooldown != 0)//If they're on cooldown you can't give them more commands.
continue
listeners += L
if(!listeners.len)
cooldown = COOLDOWN_NONE
return cooldown
//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 *= 2
//Command staff has authority
if(user.mind.assigned_role in GLOB.command_positions)
power_multiplier *= 1.4
//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 *= 2
else if (is_servant_of_ratvar(user))
power_multiplier *= 2
else if (is_devil(user))//The devil is supposed to be seductive, right?
power_multiplier *= 2
//range = 0.5 - 4.2~
//most cases = 1-2
//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)
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
/* CHECK THIS STUFF IN THE CHEM STATUS INSTEAD.
if(istype(H.neck, /obj/item/clothing/neck/petcollar))
power_multiplier *= 1.5 //Collaring players makes them more docile and accepting of their place as a pet
if(H.has_trait(TRAIT_CROCRIN_IMMUNE) || !M.canbearoused)
power_multiplier *= 1.5//Immune/asexual players are immune to the arousal based multiplier, this is to offset that so they can still be affected. Their unfamiliarty with desire makes it more on them.
*/
//Mixables
var/static/regex/enthral_words = regex("relax|obey|love|serve|docile|so easy|ara ara") //enthral_words
var/static/regex/reward_words = regex("good boy|good girl|good pet") //reward_words
var/static/regex/punish_words = regex("bad boy|bad girl|bad pet") ////punish_words
//phase 0
var/static/regex/saymyname_words = regex("say my name|who am i|whoami")
var/static/regex/wakeup_words = regex("revert|awaken|*snap")
//phase1
var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush")
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")
var/static/regex/orgasm_words = regex("cum|orgasm|climax|squirt|heyo") //lewd
//phase 2
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")
var/static/regex/run_words = regex("run")
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|objective")//What a descriptive name!
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("trip balls|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(1.5,1.5,1.3,1.2,1.1,1,0.8,0.6,0.5,0.25)
//enthral_words, reward_words, silence_words attract_words punish_words desire_words resist_words forget_words
//Tier 1
//ENTHRAL mixable
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]
//power_multiplier += (get_dist(V, user)**-2)*2 //2, 2, 0.5, 0.2, 0.125, 0.05, 0.04, 0.03, alternatively make a list and use the return as index values
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
E.cooldown += 1
//REWARD mixable
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]
//power_multiplier += (get_dist(V, user)**-2)*2 //2, 2, 0.5, 0.2, 0.125, 0.05, 0.04, 0.03, alternatively make a list and use the return as index values
if (L.canbearoused)
//E.resistanceTally -= 1
L.adjustArousalLoss(1*power_multiplier)
else
E.resistanceTally /= 2*power_multiplier
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallpraise", /datum/mood_event/enthrallpraise)
E.cooldown += 1
//PUNISH mixable
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)
power_multiplier *= distancelist[get_dist(user, V)+1]
//power_multiplier += (get_dist(V, user)**-2)*2 //2, 2, 0.5, 0.2, 0.125, 0.05, 0.04, 0.03, alternatively make a list and use the return as index values
if (L.canbearoused)
E.resistanceTally /= 1*power_multiplier
L.adjustArousalLoss(-2*power_multiplier)
else
E.resistanceTally /= 3*power_multiplier //asexuals are masochists apparently (not seriously)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallscold", /datum/mood_event/enthrallscold)
E.cooldown += 1
//teir 0
//SAY MY NAME
if((findtext(message, saymyname_words)))
for(var/V in listeners)
var/mob/living/L = V
addtimer(CALLBACK(L, /atom/movable/proc/say, "Master"), 5)//When I figure out how to do genedered names put them here
//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)
switch(E.phase)
if(0)
E.phase = 3
E.status = null
to_chat(L, "<span class='warning'>The snapping of your Master's fingers brings you back to your enthralled state, obedient and ready to serve.</b></span>")
L.SetSleeping(0)//Can you hear while asleep?
//tier 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,
C.add_trait(TRAIT_MUTE, TRAUMA_TRAIT)
else
C.silent += ((10 * power_multiplier) * E.phase)
E.cooldown += 3
//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"
E.statusStrength = (1 * power_multiplier * E.phase)
E.cooldown += 6//Too short?
//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.cooldown += 2
//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)
C.Sleeping(40)
to_chat(C, "<span class='warning'>You wake up, forgetting everything that just happened. You must've dozed off..? How embarassing!</b></span>")
switch(E.phase)
if(1 to 2)
E.phase = -1
if(3)
E.phase = 0
E.cooldown = 0
//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
//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(H.canbearoused && H.has_dna()) // probably a redundant check but for good measure
H.mob_climax(forced_climax=TRUE)
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
else
E.resistanceTally = 0 //makes resistance 0, but resets arousal, resistance buildup is faster unaroused (massively so).
E.enthrallTally += power_multiplier*1.1
to_chat(H, "<span class='warning'>Your Masters command whites out your mind in bliss!</b></span>")
E.cooldown += 6
//teir 2
//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)
var/mob/living/M = V
playsound(get_turf(M), pick('sound/effects/meow1.ogg', 'modular_citadel/sound/voice/merowr.ogg', 'modular_citadel/sound/voice/nya.ogg'), 50, 1, -1)
H.emote("me","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(20 * power_multiplier)
E.cooldown += 10
//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)//Tier 2 only
E.phase = 1
var/items = H.get_contents()
for(var/I in items)
H.dropItemToGround(I, TRUE)
to_chat(H, "<span class='warning'>Before you can even think about it, you quickly remove your clothes in response to your Master's command.</b></span>")
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)//Tier 2 only
if(L.m_intent != MOVE_INTENT_WALK)
L.toggle_move_intent()
E.cooldown += 1
//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)//Tier 2 only
if(L.m_intent != MOVE_INTENT_RUN)
L.toggle_move_intent()
E.cooldown += 1
//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(3 to INFINITY)//Tier 2 only
L.Knockdown(20 * power_multiplier * E.phase)
E.cooldown += 8
//tier3
//STATE TRIGGERS
else if((findtext(message, statecustom_words)))
for(var/V in listeners)
var/speaktrigger = ""
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
if (!E.customTriggers == list())//i.e. if it's not empty
for (var/trigger in E.customTriggers)
speaktrigger = "[trigger]\n"
L.say(speaktrigger)
//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(H, "<span class='warning'>You need to be next to your pet to give them a new trigger!</b></span>")
return
else
if (E.mental_capacity >= 10)
var/trigger = stripped_input(user, "Enter the trigger phrase", MAX_MESSAGE_LEN)
var/trigger2 = stripped_input(user, "Enter the effect.", MAX_MESSAGE_LEN)
if ((findtext(trigger, custom_words_words)))
if (trigger2 == "speak" || trigger2 == "echo")
var/trigger3 = stripped_input(user, "Enter the phrase spoken.", MAX_MESSAGE_LEN)
E.customTriggers[trigger] = list(trigger2, trigger3)
else
E.customTriggers[trigger] = trigger2
E.mental_capacity -= 10
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>")
//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(H, "<span class='warning'>You need to be next to your pet to give them a new objective!</b></span>")
return
else
user.emote("me", "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'")
if (E.mental_capacity >= 150 || message == "objective")
var/datum/objective/brainwashing/objective = stripped_input(user, "Add an objective to give your pet.", MAX_MESSAGE_LEN)
if(!LAZYLEN(objective))
return
//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")
H.objective += objective
to_chat(H, "<span class='warning'>Your master whispers you a new objective.</span>")
if(!H.objectives)
to_chat(H, "<b>[LAZYLEN(H.objectives)].</b> [H.objectives.explanation_text]")
to_chat(H, "<b>[LAZYLEN(H.objectives)].</b> [H.objectives.explanation_text]")
E.mental_capacity -= 150
//else if (E.mental_capacity >= 150)
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>")
//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 to INFINITY)//Tier 3 only
E.status = "heal"
E.statusStrength = (5 * power_multiplier)
E.cooldown += 5
//STUN
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)//Tier 3 only
L.Stun(30 * power_multiplier)
E.cooldown += 8
//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)//Tier 3 only
new /datum/hallucination/delusion(C, TRUE, null,150 * power_multiplier,0)
//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)//Tier 3 only
L.adjust_bodytemperature(10 * power_multiplier)//This seems nuts, reduced it
to_chat(L, "<span class='warning'>You feel your metabolism speed up!</b></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)//Tier 3 only
L.adjust_bodytemperature(-10 * power_multiplier)//This
to_chat(L, "<span class='warning'>You feel your metabolism slow down!</b></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
//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 to INFINITY)//Tier 3 only
E.status = "pacify"
E.cooldown += 10
//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 to INFINITY)//Tier 3 only
E.status = "charge"
E.cooldown += 10
/* THE MAYBE PILE
//MOVE
else if((findtext(message, move_words)))
var/direction
if(findtext(message, up_words))
direction = NORTH
else if(findtext(message, down_words))
direction = SOUTH
else if(findtext(message, left_words))
direction = WEST
else if(findtext(message, right_words))
direction = EAST
for(var/iter in 1 to 5 * power_multiplier)
for(var/V in listeners)
var/mob/living/L = V
addtimer(CALLBACK(GLOBAL_PROC, .proc/_step, L, direction? direction : pick(GLOB.cardinals)), 10 * (iter - 1))
//HELP INTENT
else if((findtext(message, helpintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_HELP), i * 2)
addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
i++
//DISARM INTENT
else if((findtext(message, disarmintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_DISARM), i * 2)
addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
i++
//GRAB INTENT
else if((findtext(message, grabintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_GRAB), i * 2)
addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
i++
//FLIP
else if((findtext(message, flip_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
L.emote("flip")
//SPEAK (Check what this does)
else if((findtext(message, speak_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
addtimer(CALLBACK(L, /atom/movable/proc/say, pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")), 5 * i)
i++
//SIT
else if((findtext(message, sit_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
for(var/obj/structure/chair/chair in get_turf(L))
chair.buckle_mob(L)
break
//STAND UP
else if((findtext(message, stand_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
if(L.buckled && istype(L.buckled, /obj/structure/chair))
L.buckled.unbuckle_mob(L)
//DANCE
else if((findtext(message, dance_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
addtimer(CALLBACK(L, /mob/living/.proc/emote, "dance"), 5 * i)
i++
//PLAY DEAD
else if((findtext(message, deathgasp_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
addtimer(CALLBACK(L, /mob/living/.proc/emote, "deathgasp"), 5 * i)
i++
*/
if(message_admins)
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("[key_name(user)] has said '[log_message]' with a Velvet Voice, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
SSblackbox.record_feedback("tally", "Velvet_voice", 1, log_message)
return
#undef COOLDOWN_STUN
#undef COOLDOWN_DAMAGE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

@@ -1,3 +1,33 @@
/datum/mood_event/eigenstate
mood_change = -1
description = "<span class='warning'>Where the hell am I? Is this an alternative dimension ?</span>\n"
/datum/mood_event/enthrall
mood_change = 5
description = "<span class='warning'>I am a good pet for Master.</span>\n"
/datum/mood_event/enthrallpraise
mood_change = 12
description = "<span class='warning'>I feel so happy! I'm a good pet who Master loves!</span>\n"
timeout = 400
/datum/mood_event/enthrallscold
mood_change = -12
description = "<span class='warning'>I've failed Master... What a bad, bad pet!</span>\n"//aaa I'm not kinky enough for this
timeout = 600
/datum/mood_event/enthrallmissing1
mood_change = -5
description = "<span class='warning'>I feel empty when Master's not around..</span>\n"
/datum/mood_event/enthrallmissing2
mood_change = -10
description = "<span class='warning'>I feel so lost in this complicated world without Master, where are they?!</span>\n"
/datum/mood_event/enthrallmissing3
mood_change = -15
description = "<span class='warning'>Where are you Master??!</span>\n"
/datum/mood_event/enthrallmissing4
mood_change = -25
description = "<span class='warning'>You're all alone, It's so hard to continute without your Master...</span>\n"
@@ -1,7 +1,14 @@
/datum/status_effect/chem/SGDF
id = "SGDF"
var/mob/living/fermi_Clone
alert_type = null
/*
/obj/screen/alert/status_effect/SDGF
name = "SDGF"
desc = "You've cloned yourself! How cute."
icon_state = "SDGF"
*/
/datum/status_effect/chem/SGDF/on_apply()
message_admins("SGDF status appied")
@@ -21,9 +28,9 @@
return ..()
/datum/status_effect/chem/SGDF/tick()
message_admins("SDGF ticking")
//message_admins("SDGF ticking")
if(owner.stat == DEAD)
message_admins("SGDF status swapping")
//message_admins("SGDF status swapping")
if(fermi_Clone && fermi_Clone.stat != DEAD)
if(owner.mind)
owner.mind.transfer_to(fermi_Clone)
@@ -34,6 +41,552 @@
// to_chat(owner, "<span class='notice'>[linked_extract] desperately tries to move your soul to a living body, but can't find one!</span>")
..()
/datum/status_effect/chem/BElarger
id = "BElarger"
alert_type = null
//var/list/items = list()
//var/items = o.get_contents()
//mob/living/carbon/M = M tried, no dice
//owner, tried, no dice
/datum/status_effect/chem/BElarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
var/mob/living/carbon/human/o = owner
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
//message_admins("BElarge started!")
if(o.w_uniform || o.wear_suit)
to_chat(o, "<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!</b></span>")
o.visible_message("<span class='boldnotice'>[o]'s chest suddenly bursts forth, ripping their clothes off!'</span>")
else
to_chat(o, "<span class='notice'>Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
return ..()
/datum/status_effect/chem/BElarger/tick(mob/living/carbon/human/H)//If you try to wear clothes, you fail. Slows you down if you're comically huge
var/mob/living/carbon/human/o = owner
var/obj/item/organ/genital/breasts/B = o.getorganslot("breasts")
if(!B)
o.remove_movespeed_modifier("megamilk")
o.next_move_modifier = 1
owner.remove_status_effect(src)
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(owner, "<span class='warning'>Your enormous breasts are way too large to fit anything over them!</b></span>")
//message_admins("BElarge tick!")
/*
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W)
//items |= owner.get_equipped_items(TRUE)
//owner.dropItemToGround(owner.wear_suit)
//owner.dropItemToGround(owner.w_uniform)
*/
switch(round(B.cached_size))
if(9)
if (!(B.breast_sizes[B.prev_size] == B.size))
o.remove_movespeed_modifier("megamilk")
o.next_move_modifier = 1
if(10 to INFINITY)
if (!(B.breast_sizes[B.prev_size] == B.size))
to_chat(H, "<span class='warning'>Your indulgent busom is so substantial, it's affecting your movements!</b></span>")
o.add_movespeed_modifier("megamilk", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = (round(B.cached_size) - 8))
o.next_move_modifier = (round(B.cached_size) - 8)
..()
/datum/status_effect/chem/BElarger/on_remove(mob/living/carbon/M)
owner.remove_movespeed_modifier("megamilk")
owner.next_move_modifier = 1
/datum/status_effect/chem/PElarger
id = "PElarger"
alert_type = null
/datum/status_effect/chem/PElarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
message_admins("PElarge started!")
var/mob/living/carbon/human/o = owner
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
if(o.w_uniform || o.wear_suit)
to_chat(o, "<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!</b></span>")
owner.visible_message("<span class='boldnotice'>[o]'s schlong suddenly bursts forth, ripping their clothes off!'</span>")
else
to_chat(o, "<span class='notice'>Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
return ..()
/datum/status_effect/chem/PElarger/tick(mob/living/carbon/M)
var/mob/living/carbon/human/o = owner
var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
if(!P)
o.remove_movespeed_modifier("hugedick")
o.next_move_modifier = 1
owner.remove_status_effect(src)
message_admins("PElarge tick!")
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(owner, "<span class='warning'>Your enormous package is way to large to fit anything over!</b></span>")
switch(round(P.cached_length))
if(11)
if (!(P.prev_size == P.size))
to_chat(o, "<span class='warning'>Your rascally willy has become a more managable size, liberating your movements.</b></span>")
o.remove_movespeed_modifier("hugedick")
o.next_move_modifier = 1
if(12 to INFINITY)
if (!(P.prev_size == P.size))
to_chat(o, "<span class='warning'>Your indulgent johnson is so substantial, it's affecting your movements!</b></span>")
o.add_movespeed_modifier("hugedick", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = (P.length - 11.1))
o.next_move_modifier = (round(P.length) - 11)
..()
/*//////////////////////////////////////////
Mind control functions
///////////////////////////////////////////
*/
/datum/status_effect/chem/enthrall
id = "enthrall"
alert_type = null
var/mob/living/E //E for enchanter
//var/mob/living/V = list() //V for victims
var/enthrallTally = 1 //Keeps track of the enthralling process
var/resistanceTally = 0 //Keeps track of the resistance
var/deltaResist //The total resistance added per resist click
//var/deltaEnthrall //currently unused (i think)
var/phase = 1 //-1: resisted state, due to be removed.0: sleeper agent, no effects unless triggered 1: initial, 2: 2nd stage - more commands, 3rd: fully enthralled, 4th Mindbroken
var/status = null //status effects
var/statusStrength = 0 //strength of status effect
var/mob/living/master //Enchanter's person
var/enthrallID //Enchanter's ckey
var/enthrallGender //Use master or mistress
//var/mob/living/master == null
var/mental_capacity //Higher it is, lower the cooldown on commands, capacity reduces with resistance.
//var/mental_cost //Current cost of custom triggers
//var/mindbroken = FALSE //Not sure I use this, replaced with phase 4
var/datum/weakref/redirect_component1 //resistance
var/datum/weakref/redirect_component2 //say
var/distancelist = list(4,3,2,1.5,1,0.8,0.6,0.4,0.2) //Distance multipliers
var/withdrawal = FALSE //withdrawl
var/withdrawalTick = 0 //counts how long withdrawl is going on for
var/list/customTriggers = list() //the list of custom triggers (maybe have to split into two)
var/cooldown = 0
/datum/status_effect/chem/enthrall/on_apply(mob/living/carbon/M)
if(M.key == enthrallID)
owner.remove_status_effect(src)//This shouldn't happen, but just in case
redirect_component1 = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) //Do resistance calc if resist is pressed#
redirect_component2 = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_SAY = CALLBACK(src, .proc/owner_say)))) //Do resistance calc if resist is pressed
//Might need to add redirect component for listening too.
var/obj/item/organ/brain/B = M.getorganslot(ORGAN_SLOT_BRAIN) //It's their brain!
mental_capacity = 500 - B.get_brain_damage()
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "enthrall", /datum/mood_event/enthrall)
/datum/status_effect/chem/enthrall/tick(mob/living/carbon/M)
//chem calculations
if (owner.reagents.has_reagent("MKUltra"))
if (phase >= 2)
enthrallTally += phase
else
if (phase < 3)
deltaResist += 5//If you've no chem, then you break out quickly
if(prob(20))
to_chat(owner, "<span class='notice'><i>Your mind starts to restore some of it's clarity as you feel the effects of the drug wain.</i></span>")
if (mental_capacity <= 500 || phase == 4)
if (owner.reagents.has_reagent("mannitol"))
mental_capacity += 1
if (owner.reagents.has_reagent("neurine"))
mental_capacity += 2
//mindshield check
if(M.has_trait(TRAIT_MINDSHIELD))
resistanceTally += 5
if(prob(20))
to_chat(owner, "<span class='notice'><i>You feel lucidity returning to your mind as the mindshield buzzes, attempting to return your brain to normal function.</i></span>")
//phase specific events
switch(phase)
if(-1)//fully removed
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "enthrall")
owner.remove_status_effect(src)
else if(0)// sleeper agent
return
else if(1)//Initial enthrallment
if (enthrallTally > 100)
phase += 1
mental_capacity -= resistanceTally//leftover resistance per step is taken away from mental_capacity.
enthrallTally = 0
to_chat(owner, "<span class='notice'><i>Your conciousness slips, as you sink deeper into trance.</i></span>")
else if (resistanceTally > 100)
enthrallTally *= 0.5
phase = -1
resistanceTally = 0
to_chat(owner, "<span class='notice'><i>You break free of the influence in your mind, your thoughts suddenly turning lucid!</i></span>")
owner.remove_status_effect(src) //If resisted in phase 1, effect is removed.
if(prob(10))
to_chat(owner, "<span class='notice'><i>[pick("It feels so good to listen to [master.name].", "You can't keep your eyes off [master.name].", "[master.name]'s voice is making you feel so sleepy.", "You feel so comfortable with [master.name]", "[master.name] is so sexy and dominant, it feels right to obey them.")].</i></span>")
else if (2) //partially enthralled
if (enthrallTally > 150)
phase += 1
mental_capacity -= resistanceTally//leftover resistance per step is taken away from mental_capacity.
enthrallTally = 0
to_chat(owner, "<span class='notice'><i>Your mind gives, eagerly obeying and serving [master.name].</i></span>")
to_chat(owner, "<span class='warning'><i>You are now fully enthralled to [master.name], and eager to follow their commands. However you find that in your intoxicated state you are much less likely to resort to violence, unless it is to defend your [enthrallGender]. Equally you are unable to commit suicide, even if ordered to, as you cannot server your [enthrallGender] in death. </i></span>")//If people start using this as an excuse to be violent I'll just make them all pacifists so it's not OP.
else if (resistanceTally > 150)
enthrallTally *= 0.5
phase -= 1
resistanceTally = 0
to_chat(owner, "<span class='notice'><i>You manage to shake some of the entrancement from your addled mind, however you can still feel yourself drawn towards [master.name].</i></span>")
//owner.remove_status_effect(src) //If resisted in phase 1, effect is removed. Not at the moment,
else if (3)//fully entranced
if (resistanceTally >= 250 && withdrawalTick >= 150)
enthrallTally = 0
phase -= 1
resistanceTally = 0
to_chat(owner, "<span class='notice'><i>The separation from you [enthrallGender] sparks a small flame of resistance in yourself, as your mind slowly starts to return to normal.</i></span>")
else if (4) //mindbroken
if (mental_capacity >= 499 || owner.getBrainLoss() >=20 || !owner.reagents.has_reagent("MKUltra"))
phase = 2
mental_capacity = 500
customTriggers = list()
to_chat(owner, "<span class='notice'><i>Your mind starts to heal, fixing the damage caused by the massive ammounts of chem injected into your system earlier, .</i></span>")
M.slurring = 0
M.confused = 0
else
return//If you break the mind of someone, you can't use status effects on them.
//distance calculations
switch(get_dist(master, owner))
if(0 to 8)//If the enchanter is within range, increase enthrallTally, remove withdrawal subproc and undo withdrawal effects.
enthrallTally += distancelist[get_dist(master, owner)+1]
withdrawal = FALSE
if(withdrawalTick > 0)
withdrawalTick -= 2
M.hallucination = max(0, M.hallucination - 2)
M.stuttering = max(0, M.stuttering - 2)
M.jitteriness = max(0, M.jitteriness - 2)
if(9 to INFINITY)//If
withdrawal = TRUE
//Withdrawal subproc:
if (withdrawal == TRUE)//Your minions are really REALLY needy.
switch(withdrawalTick)//denial
if(20 to 40)//Gives wiggle room, so you're not SUPER needy
if(prob(10))
to_chat(owner, "You're starting to miss your [enthrallGender].")
if(prob(10))
owner.adjustBrainLoss(0.5)
to_chat(owner, "They'll surely be back soon") //denial
if(41)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing1", /datum/mood_event/enthrallmissing1)
if(42 to 65)//barganing
if(prob(10))
to_chat(owner, "They are coming back, right...?")
owner.adjustBrainLoss(1)
if(prob(20))
to_chat(owner, "I just need to be a good pet for [enthrallGender], they'll surely return if I'm a good pet.")
owner.adjustBrainLoss(-2)
if(66)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1") //Why does this not work?
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing2", /datum/mood_event/enthrallmissing2)
owner.stuttering += 20
owner.jitteriness += 20
if(67 to 90) //anger
if(prob(30))
addtimer(CALLBACK(M, /mob/verb/a_intent_change, INTENT_HARM), 2)
addtimer(CALLBACK(M, /mob/proc/click_random_mob), 2)
to_chat(owner, "You suddenly lash out at the station in anger for it keeping you away from your [enthrallGender].")
if(90)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2") //Why does this not work?
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing3", /datum/mood_event/enthrallmissing3)
to_chat(owner, "<span class='warning'><i>You need to find your [enthrallGender] at all costs, you can't hold yourself back anymore.</i></span>")
if(91 to 120)//depression
if(prob(20))
owner.adjustBrainLoss(1)
owner.stuttering += 2
owner.jitteriness += 2
if(prob(25))
M.hallucination += 2
if(121)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing4", /datum/mood_event/enthrallmissing4)
to_chat(owner, "<span class='warning'><i>You can hardly find the strength to continue without your [enthrallGender].</i></span>")
if(120 to 140) //depression
if(prob(25))
owner.SetStun(20, 0)
owner.emote("cry")//does this exist?
to_chat(owner, "You're unable to hold back your tears, suddenly sobbing as the desire to see your [enthrallGender] oncemore overwhelms you.")
owner.adjustBrainLoss(2)
owner.stuttering += 2
owner.jitteriness += 2
if(prob(10))
deltaResist += 5
if(140 to INFINITY) //acceptance
if(prob(20))
deltaResist += 5
if(prob(20))
to_chat(owner, "Maybe you'll be okay without your [enthrallGender].")
if(prob(10))
owner.adjustBrainLoss(1)
M.hallucination += 5
withdrawalTick++
//Status subproc - statuses given to you from your Master
//currently 3 statuses; antiresist -if you press resist, increases your enthrallment instead, HEAL - which slowly heals the pet, CHARGE - which breifly increases speed, PACIFY - makes pet a pacifist.
if (!status == null)
switch(status)
if("Antiresist")
if (statusStrength == 0)
status = null
to_chat(owner, "You feel able to resist oncemore.")
else
statusStrength -= 1
else if("heal")
if (statusStrength == 0)
status = null
to_chat(owner, "You finish licking your wounds.")
else
statusStrength -= 1
owner.heal_overall_damage(1, 1, 0, FALSE, FALSE)
cooldown += 1 //Cooldown doesn't process till status is done
else if("charge")
owner.add_trait(TRAIT_GOTTAGOFAST, "MKUltra")
status = "charged"
to_chat(owner, "Your [enthrallGender]'s order fills you with a burst of speed!")
else if ("charged")
if (statusStrength == 0)
status = null
owner.remove_trait(TRAIT_GOTTAGOFAST, "MKUltra")
owner.Knockdown(30)
to_chat(owner, "Your body gives out as the adrenaline in your system runs out.")
else
statusStrength -= 1
cooldown += 1 //Cooldown doesn't process till status is done
else if ("pacify")
owner.add_trait(TRAIT_PACIFISM, "MKUltra")
status = null
//Truth serum?
//adrenals?
//M.next_move_modifier *= 0.5
//M.adjustStaminaLoss(-5*REM)
//final tidying
resistanceTally += deltaResist
deltaResist = 0
if (cooldown > 0)
cooldown -= (1 + (mental_capacity/1000 ))
else
to_chat(master, "<span class='notice'><i>Your pet [owner.name] appears to have finished internalising your last command.</i></span>")
//Check for proximity of master DONE
//Place triggerreacts here - create a dictionary of triggerword and effect.
//message enthrallID "name appears to have mentally processed their last command."
/datum/status_effect/chem/enthrall/on_remove(mob/living/carbon/M)
qdel(redirect_component1.resolve())
redirect_component1 = null
qdel(redirect_component2.resolve())
redirect_component2 = null
/*
/datum/status_effect/chem/enthrall/mob/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(enthrallID.name in message || enthrallID.first_name in message)
return
else
. = ..()
*/
/datum/status_effect/chem/enthrall/proc/on_hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
var/mob/living/carbon/C = owner
for (var/trigger in customTriggers)
if (trigger == message)//if trigger1 is the message
//Speak (Forces player to talk)
if (customTriggers[trigger][1] == "speak")//trigger2
C.visible_message("<span class='notice'>Your mouth moves on it's own, before you can even catch it. Though you find yourself fully believing in the validity of what you just said and don't think to question it.</span>")
(C.say(customTriggers[trigger][2]))//trigger3
//Echo (repeats message!)
else if (customTriggers[trigger][1] == "echo")//trigger2
(to_chat(owner, customTriggers[trigger][2]))//trigger3
//Shocking truth!
else if (customTriggers[trigger] == "shock")
if (C.canbearoused)
C.electrocute_act(10, src, 1, FALSE, FALSE, FALSE, TRUE)//I've no idea how strong this is
C.adjustArousalLoss(5)
to_chat(owner, "<span class='notice'><i>Your muscles seize up, then start spasming wildy!</i></span>")
else
C.electrocute_act(15, src, 1, FALSE, FALSE, FALSE, TRUE)//To make up for the lack of effect
//wah intensifies
else if (customTriggers[trigger][1] == "cum")//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
if (C.canbearoused)
if (C.getArousalLoss() > 80)
C.mob_climax(forced_climax=TRUE)
else
C.adjustArousalLoss(10)
else
C.throw_at(get_step_towards(speaker,C), 3, 1) //cut this if it's too hard to get working
//kneel (knockdown)
else if (customTriggers[trigger][1] == "kneel")//as close to kneeling as you can get, I suppose.
C.Knockdown(20)
//strip (some) clothes
else if (customTriggers[trigger][1] == "strip")//This wasn't meant to just be a lewd thing oops
var/mob/living/carbon/human/o = owner
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
C.visible_message("<span class='notice'>You feel compelled to strip your clothes.</span>")
//add more fun stuff!
return
/*
/datum/status_effect/chem/enthrall/proc/owner_withdrawal(mob/living/carbon/M)
//3 stages, each getting worse
*/
/datum/status_effect/chem/enthrall/proc/owner_resist(mob/living/carbon/M)
if (status == "Sleeper" || phase == 0)
return
else if (phase == 4)
to_chat(owner, "<span class='notice'><i>Your mind is too far gone to even entertain the thought of resisting.</i></span>")
return
else if (phase == 3 || withdrawal == FALSE)
to_chat(owner, "<span class='notice'><i>The presence of your [enthrallGender] fully captures the horizon of your mind, removing any thoughts of resistance.</i></span>")
return
else if (status == "Antiresist")//If ordered to not resist; resisting while ordered to not makes it last longer, and increases the rate in which you are enthralled.
if (statusStrength > 0)
to_chat(owner, "<span class='notice'><i>The order from your [enthrallGender] to give in is conflicting with your attempt to resist, drawing you deeper into trance.</i></span>")
statusStrength += 1
enthrallTally += 1
return
else
status = null
if (deltaResist != 0)//So you can't spam it, you get one deltaResistance per tick.
deltaResist += 0.1 //Though I commend your spamming efforts.
return
if(prob(10))
M.emote("me",1,"squints, shaking their head for a moment.")//shows that you're trying to resist sometimes
to_chat(owner, "You attempt to shake the mental cobwebs from your mind!")
//base resistance
if (M.canbearoused)
deltaResist*= ((100 - M.arousalloss/100)/100)//more aroused you are, the weaker resistance you can give
else
deltaResist *= 0.2
//chemical resistance, brain and annaphros are the key to undoing, but the subject has to to be willing to resist.
if (owner.reagents.has_reagent("mannitol"))
deltaResist *= 1.25
if (owner.reagents.has_reagent("neurine"))
deltaResist *= 1.5
if (!owner.has_trait(TRAIT_CROCRIN_IMMUNE) && M.canbearoused)
if (owner.reagents.has_reagent("anaphro"))
deltaResist *= 1.5
if (owner.reagents.has_reagent("anaphro+"))
deltaResist *= 2
if (owner.reagents.has_reagent("aphro"))
deltaResist *= 0.75
if (owner.reagents.has_reagent("aphro+"))
deltaResist *= 0.5
//Antag resistance
//cultists are already brainwashed by their god
if(iscultist(owner))
deltaResist *= 2
else if (is_servant_of_ratvar(owner))
deltaResist *= 2
//antags should be able to resist, so they can do their other objectives. This chem does frustrate them, but they've all the tools to break free when an oportunity presents itself.
else if (owner.mind.assigned_role in GLOB.antagonists)
deltaResist *= 1.8
//role resistance
//Chaplains are already brainwashed by their god
if(owner.mind.assigned_role == "Chaplain")
deltaResist *= 1.5
//Command staff has authority,
if(owner.mind.assigned_role in GLOB.command_positions)
deltaResist *= 1.4
//if(owner.has_status == "sub"); power_multiplier *= 0.8 //for skylar //I'm kidding <3
//Chemists should be familiar with drug effects
if(owner.mind.assigned_role == "Chemist")
deltaResist *= 1.3
//Happiness resistance
//Your Thralls are like pets, you need to keep them happy.
if(owner.nutrition < 250)
deltaResist += (250-owner.nutrition)/100
if(owner.health < 100)//Harming your thrall will make them rebel harder.
deltaResist *= ((120-owner.health)/100)+1
//Add cold/hot, oxygen, sanity, happiness? (happiness might be moot, since the mood effects are so strong)
//Mental health could play a role too in the other direction
//If master gives you a collar, you get a sense of pride
if(istype(M.wear_neck, /obj/item/clothing/neck/petcollar))
deltaResist *= 0.5
if(owner.has_trait(TRAIT_CROCRIN_IMMUNE) || !owner.canbearoused)
deltaResist *= 0.75//Immune/asexual players are immune to the arousal based multiplier, this is to offset that so they can still be affected. Their unfamiliarty with desire makes it more on them.
if (deltaResist>0)//just in case
deltaResist /= phase//later phases require more resistance
/datum/status_effect/chem/enthrall/proc/owner_say(message) //I can only hope this works
var/static/regex/owner_words = regex("[master.real_name]|[master.first_name()]")
if(findtext(message, owner_words))
message = replacetext(lowertext(message), lowertext(master.real_name), "[enthrallGender]")
message = replacetext(lowertext(message), lowertext(master.name), "[enthrallGender]")
return message
/*
/datum/status_effect/chem/OwO
id = "OwO"
/datum/status_effect/chem/PElarger/tick(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, "ove", "uv")
message = replacetext(message, "th", "ff")
message = replacetext(message, "l", "w")
message = replacetext(message, "r", "w")
if(prob(20))
message = replacetext(message, ".", "OwO.")
else if(prob(30))
message = replacetext(message, ".", "uwu.")
message = lowertext(message)
*/
/*Doesn't work
/datum/status_effect/chem/SDGF/candidates
id = "SGDFCandi"
var/mob/living/fermi_Clone
@@ -42,3 +595,4 @@
/datum/status_effect/chem/SDGF/candidates/on_apply()
candies = pollGhostCandidates("Do you want to play as a clone and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies
return ..()
*/
@@ -7,6 +7,11 @@
slot = "breasts"
w_class = 3
size = BREASTS_SIZE_DEF
var/cached_size = null//for enlargement
var/prev_size //For flavour texts
var/breast_sizes = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "huge", "flat")
var/breast_values = list ("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
var/statuscheck = FALSE
fluid_id = "milk"
var/amount = 2
producing = TRUE
@@ -19,6 +24,7 @@
/obj/item/organ/genital/breasts/Initialize()
. = ..()
reagents.add_reagent(fluid_id, fluid_max_volume)
prev_size = size
/obj/item/organ/genital/breasts/on_life()
if(QDELETED(src))
@@ -44,10 +50,14 @@
desc = "You see a pair of breasts."
else
desc = "You see some breasts, they seem to be quite exotic."
if (size)
desc += " You estimate that they're [uppertext(size)]-cups."
else
desc += " You wouldn't measure them in cup sizes."
if(isnum(size))
desc = "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [size]cm in diameter."
else if (!isnum(size))
if (size == "flat")
desc += " They're very small and flatchested, however."
else
desc += " You estimate that they're [uppertext(size)]-cups."
if(producing && aroused_state)
desc += " They're leaking [fluid_id]."
if(owner)
@@ -57,3 +67,65 @@
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[owner.dna.features["breasts_color"]]"
//Allows breasts to grow and change size, with sprite changes too.
//maximum wah
//Comical sizes slow you down in movement and actions.
//Rediculous sizes remove hands.
//Should I turn someone with meter wide... assets into a blob?
//this is far too lewd wah
/obj/item/organ/genital/breasts/update_size()//wah
//var/mob/living/carbon/human/o = owner
//var/obj/item/organ/genital/breasts/B = o.getorganslot("breasts")
if (cached_size == null)
prev_size = size
return
//message_admins("Breast size at start: [size], [cached_size], [owner]")
if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
to_chat(owner, "<span class='warning'>You feel your breasts shrinking away from your body as your chest flattens out.</b></span>")
src.Remove(owner)
switch(round(cached_size))
if(0) //If flatchested
size = "flat"
if(statuscheck == TRUE)
message_admins("Attempting to remove.")
owner.remove_status_effect(/datum/status_effect/chem/BElarger)
statuscheck = FALSE
if(1 to 8) //If modest size
size = breast_sizes[round(cached_size)]
if(statuscheck == TRUE)
message_admins("Attempting to remove.")
owner.remove_status_effect(/datum/status_effect/chem/BElarger)
statuscheck = FALSE
if(9 to 15) //If massive
size = breast_sizes[round(cached_size)]
if(statuscheck == FALSE)
message_admins("Attempting to apply.")
owner.apply_status_effect(/datum/status_effect/chem/BElarger)
statuscheck = TRUE
if(16 to INFINITY) //if Rediculous
size = cached_size
//message_admins("1. [breast_values[size]] vs [breast_values[prev_size]] || [size] vs [prev_size]")
//message_admins("1. [prev_size] vs [breast_values[size]]")
if(round(cached_size) < 16)//Because byond doesn't count from 0, I have to do this.
if (prev_size == 0)
prev_size = "flat"
if(size == 0)//Bloody byond with it's counting from 1
size = "flat"
if(isnum(prev_size))
prev_size = breast_sizes[prev_size]
//message_admins("2. [breast_values[size]] vs [breast_values[prev_size]] || [size] vs [prev_size]")
if (breast_values[size] > breast_values[prev_size])
to_chat(owner, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
else if (breast_values[size] < breast_values[prev_size])
to_chat(owner, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
prev_size = size
else if (cached_size == 16.2)
to_chat(owner, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a hefty [uppertext(size)]cm diameter bosom.</b></span>")// taking both of your hands to hold!.</b></span>")
@@ -267,7 +267,13 @@
if(src && !QDELETED(src))
dna.species.handle_genitals(src)
/mob/living/carbon/human/proc/Force_update_genitals()
dna.species.handle_genitals(src)
//dna.species.handle_breasts(src)
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)
message_admins("attempting to update sprite")
if(!H)//no args
CRASH("H = null")
if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done
@@ -276,15 +282,12 @@
return
if(H.has_trait(TRAIT_HUSK))
return
var/list/genitals_to_add = list()
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER)
var/list/standing = list()
var/size = null
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
//start scanning for genitals
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
for(var/obj/item/organ/O in H.internal_organs)
@@ -293,7 +296,6 @@
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
genitals_to_add += H.getorganslot(G.slot)
//Now we added all genitals that aren't internal and should be rendered
//start applying overlays
for(var/layer in relevant_layers)
var/layertext = genitals_layertext(layer)
@@ -348,3 +350,68 @@
for(var/L in relevant_layers)
H.apply_overlay(L)
/*
/datum/species/proc/handle_breasts(mob/living/carbon/human/H)
//check for breasts first!
var/obj/item/organ/genital/breasts/B = H.getorganslot("breasts")
if(!B)
return
message_admins("attempting to update sprite in a hacky way")
///obj/item/organ/genital/breasts/update_icon(/obj/item/organ/genital) Where did this come from?
//Variables:
var/size = B.size
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER)
var/datum/sprite_accessory/S = GLOB.breasts_shapes_list[B.shape]
var/list/standing = list()
if(!S || S.icon_state == "none")
return
for(var/layer in relevant_layers)
var/layertext = genitals_layertext(layer)
S = GLOB.breasts_shapes_list[B.shape]
var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
//If breasts are hueg (larger than 5 only have one sprite atm)
if (size > 5)
genital_overlay.icon_state = "[B.slot]_[B.shape]_[size]_0_[layertext]"//I haven't done around sizes above 5, I dunno how..!
else
genital_overlay.icon_state = "[B.slot]_[S.icon_state]_[size]_[B.aroused_state]_[layertext]"
//center icon
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
//Check skin colour
if(use_skintones && H.dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
else
switch(S.color_src)
if("vag_color")
genital_overlay.color = "#[H.dna.features["vag_color"]]"
if(MUTCOLORS)
if(fixed_mut_color)
genital_overlay.color = "#[fixed_mut_color]"
else
genital_overlay.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
genital_overlay.color = "#[fixed_mut_color2]"
else
genital_overlay.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
genital_overlay.color = "#[fixed_mut_color3]"
else
genital_overlay.color = "#[H.dna.features["mcolor3"]]"
standing += genital_overlay
//Standing..?
if(LAZYLEN(standing))
H.overlays_standing[layer] = standing.Copy()
standing = list()
for(var/L in relevant_layers)
H.apply_overlay(L)
*/
@@ -18,25 +18,64 @@
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/dickflags = list()
var/list/knotted_types = list("knotted", "barbed, knotted")
var/statuscheck = FALSE
var/prev_size = 6
/obj/item/organ/genital/penis/update_size()
if(length == cached_length)
return
switch(length)
if(-INFINITY to 5)
var/mob/living/carbon/human/o = owner
if(cached_length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
to_chat(o, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
P.Remove(o)
switch(round(cached_length))
if(0 to 4) //If modest size
length = cached_length
size = 1
if(5 to 9)
if(statuscheck == TRUE)
message_admins("Attempting to remove.")
o.remove_status_effect(/datum/status_effect/chem/PElarger)
statuscheck = FALSE
if(5 to 8) //If modest size
length = cached_length
size = 2
if(9 to INFINITY)
size = 3//no new sprites for anything larger yet
/* if(9 to 15)
size = 3
if(statuscheck == TRUE)
message_admins("Attempting to remove.")
o.remove_status_effect(/datum/status_effect/chem/PElarger)
statuscheck = FALSE
if(9 to INFINITY) //If massive
length = cached_length
size = 3 //no new sprites for anything larger yet
if(statuscheck == FALSE)
message_admins("Attempting to apply.")
o.remove_status_effect(/datum/status_effect/chem/PElarger)
statuscheck = TRUE
if(15 to INFINITY)
size = 3*/
length = cached_length
size = 3 //no new sprites for anything larger yet
if(statuscheck == FALSE)
message_admins("Attempting to apply.")
o.apply_status_effect(/datum/status_effect/chem/PElarger)
statuscheck = TRUE
message_admins("Pinas size: [size], [cached_length], [o]")
message_admins("2. size vs prev_size")
if (round(length) > round(prev_size))
to_chat(o, "<span class='warning'>Your [pick("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "baloney pony", "schlanger")] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(length)] inch penis.</b></span>")
else if (round(length) < round(prev_size))
to_chat(o, "<span class='warning'>Your [pick("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "baloney pony", "schlanger")] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(length)] inch penis.</b></span>")
prev_size = length
icon_state = sanitize_text("penis_[shape]_[size]")
//update_body()
//P.update_icon() //Either of these don't work, why???
girth = (length * girth_ratio)
cached_length = length
//var/mob/living/carbon/human/H = owner
//H.update_genitals()
//owner.update_genitals()
//I have no idea on how to update sprites and I hate it
/obj/item/organ/genital/penis/update_appearance()
//var/mob/living/carbon/o = owner
var/string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]"
icon_state = sanitize_text(string)
var/lowershape = lowertext(shape)
@@ -49,6 +88,7 @@
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[owner.dna.features["cock_color"]]"
//owner.update_body()
/obj/item/organ/genital/penis/update_link()
if(owner)
@@ -0,0 +1,16 @@
//Fermiclothes!
//Clothes made from FermiChem
/obj/item/clothing/head/hattip //I wonder if anyone else has played cryptworlds
name = "Sythetic hat"
con = 'icons/obj/clothing/hats.dmi'
icon_state = "top_hat"
desc = "A sythesized hat, you can't seem to take it off. And tips their hat."
/obj/item/clothing/head/hattip/attack_hand(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.head)
M.emote("me",1,"tips their hat.",TRUE)
return
return ..()
@@ -12,10 +12,10 @@
id = "fermi"
taste_description = "If affection had a taste, this would be it."
/datum/reagent/fermi/on_mob_life(mob/living/carbon/M)
///datum/reagent/fermi/on_mob_life(mob/living/carbon/M)
//current_cycle++
holder.remove_reagent(src.id, metabolization_rate / M.metabolism_efficiency, FALSE) //fermi reagents stay longer if you have a better metabolism
return ..()
//holder.remove_reagent(src.id, metabolization_rate / M.metabolism_efficiency, FALSE) //fermi reagents stay longer if you have a better metabolism
//return ..()
/datum/reagent/fermi/overdose_start(mob/living/carbon/M)
current_cycle++
@@ -29,42 +29,31 @@
name = "Eigenstasium"
id = "eigenstate"
description = "A strange mixture formed from a controlled reaction of bluespace with plasma, that causes localised eigenstate fluxuations within the patient"
taste_description = "."
color = "#60A584" // rgb: 96, 0, 255
taste_description = "wiggly"
color = "#5020H4" // rgb: 50, 20, 255
overdose_threshold = 15
addiction_threshold = 20
metabolization_rate = 0.5 * REAGENTS_METABOLISM
addiction_stage2_end = 30
addiction_stage3_end = 40
addiction_stage4_end = 43 //Incase it's too long
var/turf/open/location_created = null
var/location_created
var/turf/open/location_return = null
var/addictCyc1 = 1
var/addictCyc2 = 1
var/addictCyc3 = 1
var/addictCyc4 = 1
var/addictCyc1 = 0
var/addictCyc2 = 0
var/addictCyc3 = 0
var/addictCyc4 = 0
var/mob/living/fermi_Tclone = null
var/teleBool = FALSE
mob/living/carbon/purgeBody
/*
/datum/reagent/fermi/eigenstate/oew()
. = ..() //Needed!
location_created = get_turf(src) //Sets up coordinate of where it was created
message_admins("Attempting to get creation location from on_new() [location_created]")
//..()s
*/
/datum/reagent/fermi/eigenstate/on_new()
//obj/item/reagent/fermi/eigenstate/Initialize()
//datum/reagent/fermi/eigenstate/Initialize()
. = ..() //Needed!
//if(holder && holder.my_atom)
location_created = get_turf(loc) //Sets up coordinate of where it was created
message_admins("Attempting to get creation location from init() [location_created]")
//..()
*/
//Main functions
/datum/reagent/fermi/eigenstate/on_mob_life(mob/living/M) //Teleports to chemistry!
switch(current_cycle)
if(0)
@@ -76,7 +65,7 @@
do_sparks(5,FALSE,M)
if(prob(20))
do_sparks(5,FALSE,M)
message_admins("eigenstate state: [current_cycle]")
//message_admins("eigenstate state: [current_cycle]")
..()
/datum/reagent/fermi/eigenstate/on_mob_delete(mob/living/M) //returns back to original location
@@ -95,10 +84,10 @@
do_sparks(5,FALSE,src)
do_teleport(M, get_turf(M), 10, asoundin = 'sound/effects/phasein.ogg')
do_sparks(5,FALSE,src)
holder.remove_reagent("eigenstate",0.5)//So you're not stuck for 10 minutes teleporting
holder.remove_reagent(src.id, 0.5)//So you're not stuck for 10 minutes teleporting
..() //loop function
//Addiction
/datum/reagent/fermi/eigenstate/addiction_act_stage1(mob/living/M) //Welcome to Fermis' wild ride.
switch(src.addictCyc1)
if(1)
@@ -110,7 +99,7 @@
/datum/reagent/fermi/eigenstate/addiction_act_stage2(mob/living/M)
switch(src.addictCyc2)
if(1)
if(0)
to_chat(M, "<span class='userdanger'>You start to convlse violently as you feel your consciousness split and merge across realities as your possessions fly wildy off your body.</span>")
M.Jitter(50)
M.Knockdown(100)
@@ -163,7 +152,7 @@
/datum/reagent/fermi/eigenstate/addiction_act_stage4(mob/living/M) //Thanks for riding Fermis' wild ride. Mild jitter and player buggery.
switch(src.addictCyc4)
if(1)
if(0)
do_sparks(5,FALSE,M)
do_teleport(M, get_turf(M), 2, no_effects=TRUE) //teleports clone so it's hard to find the real one!
do_sparks(5,FALSE,M)
@@ -172,9 +161,9 @@
M.Knockdown(0)
to_chat(M, "<span class='userdanger'>You feel your eigenstate settle, snapping an alternative version of yourself into reality. All your previous memories are lost and replaced with the alternative version of yourself. This version of you feels more [pick("affectionate", "happy", "lusty", "radical", "shy", "ambitious", "frank", "voracious", "sensible", "witty")] than your previous self, sent to god knows what universe.</span>")
M.emote("me",1,"flashes into reality suddenly, gasping as they gaze around in a bewildered and highly confused fashion!",TRUE)
M.reagents.remove_all_type(/datum/reagent/toxin, 5*REM, 0, 1)
for(var/i in M.mood_events)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, i.id)
M.reagents.remove_all_type(/datum/reagent, 100, 0, 1)
for (var/datum/mood_event/i in M)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, i) //Why does this not work?
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "Alternative dimension", /datum/mood_event/eigenstate)
@@ -185,11 +174,49 @@
..()
. = 1
//TODO
///datum/reagent/fermi/eigenstate/overheat_explode(mob/living/M)
// return
//eigenstate END
/*SDGF
////////////////////////////////////////////////////
// synthetic-derived growth factor //
//////////////////////////////////////////////////
WHAT IT DOES
Several outcomes are possible (in priority order):
Before the chem is even created, there is a risk of the reaction "exploding", which produces an angry teratoma that attacks the player.
0. Before the chem is activated, the purity is checked, if the purity of the reagent is less than 0.5, then sythetic-derived zombie factor is metabolised instead
0.1 If SDZF is injected, the chem appears to act the same as normal, with nutrition gain, until the end, where it becomes toxic instead, giving a short window of warning to the player
0.1.2 If the player can take pent in time, the player will spawn a hostile teratoma on them (less damaging), if they don't, then a zombie is spawned instead, with a small defence increase propotional to the volume
0.2 If the purity is above 0.5, then the remaining impure volume created SDGFtox instead, which reduces blood volume and causes clone damage
1.Normal function creates a (another)player controlled clone of the player, which is spawned nude, with damage to the clone
1.1 The remaining volume is transferred to the clone, which heals it over time, thus the player has to make a substantial ammount of the chem in order to produce a healthy clone
1.2 If the player is infected with a zombie tumor, the tumor is transferred to the ghost controlled clone ONLY.
2. If no player can be found, a brainless clone is created over a long period of time, this body has no controller.
2.1 If the player dies with a clone, then they play as the clone instead. However no memories are retained after splitting.
3. If there is already a clone, then SDGF heals clone, fire and brute damage slowly. This shouldn't normalise this chem as the de facto clone healing chem, as it will always try to make a ghost clone, and then a brainless clone first.
4. If there is insuffient volume to complete the cloning process, there are two outcomes
4.1 At lower volumes, the players nutrition and blood is refunded, with light healing
4.2 At higher volumes a stronger heal is applied to the user
IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
1. The most important factor is the required volume, this is easily edited with the metabolism rate, this chem is HARD TO MAKE, You need to make a lot of it and it's a substantial effort on the players part. There is also a substantial risk; you could spawn a hotile teratoma during the reation, you could damage yourself with clone damage, you could accidentally spawn a zombie... Basically, you've a good chance of killing yourself.
1.1 Additionally, if you're trying to make SDZF purposely, you've no idea if you have or not, and that reaction is even harder to do. Plus, the player has a huge time window to get to medical to deal with it. If you take pent while it's in you, it'll be removed before it can spawn, and only spawns a teratoma if it's late stage.
2. The rate in which the clone is made, This thing takes time to produce fruits, it slows you down and makes you useless in combat/working. Basically you can't do anything during it. It will only get you killed if you use it in combat, If you do use it and you spawn a player clone, they're gimped for a long time, as they have to heal off the clone damage.
3. The healing - it's pretty low and a cyropod is more Useful
4. If you're an antag, you've a 50% chance of making a clone that will help you with your efforts, and you've no idea if they will or not. While clones can't directly harm you and care for you, they can hinder your efforts.
5. If people are being arses when they're a clone, slap them for it, they are told to NOT bugger around with someone else character, if it gets bad I'll add a blacklist, or do a check to see if you've played X amount of hours.
5.1 Another solution I'm okay with is to rename the clone to [M]'s clone, so it's obvious, this obviously ruins anyone trying to clone themselves to get an alibi however. I'd prefer this to not be the case.
5.2 Additionally, this chem is a soft buff to changelings, which apparently need a buff!
5.3 Other similar things exist already though in the codebase; impostors, split personalites, abductors, ect.
6. Giving this to someone without concent is against space law and gets you sent to gulag.
*/
//Clone serum #chemClone
/datum/reagent/fermi/SDGF //vars, mostly only care about keeping track if there's a player in the clone or not.
name = "synthetic-derived growth factor"
@@ -198,61 +225,42 @@
color = "#60A584" // rgb: 96, 0, 255
var/playerClone = FALSE
var/unitCheck = FALSE
metabolization_rate = 0.25 * REAGENTS_METABOLISM
metabolization_rate = 0.5 * REAGENTS_METABOLISM
//var/datum/status_effect/chem/SDGF/candidates/candies
var/list/candies = list()
//var/polling = FALSE
var/list/result = list()
var/list/group = null
var/pollStarted = FALSE
var/location_created
var/startHunger
//var/fClone_current_controller = OWNER
//var/mob/living/split_personality/clone//there's two so they can swap without overwriting
//var/mob/living/split_personality/owner
//var/mob/living/carbon/SM
/*
/datum/reagent/fermi/SDGF/New()
candidates = pollGhostCandidates("Do you want to play as a clone and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies
message_admins("Attempting to poll")
^^^breaks everything
*/
/datum/reagent/fermi/proc/sepPoll()
var/list/procCandies = list()
procCandies = pollGhostCandidates("Do you want to play as a clone and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 20) // see poll_ignore.dm, should allow admins to ban greifers or bullies
return procCandies
/*if(1) //I'm not sure how pollCanditdates works, so I did this. Gives a chance for people to say yes.
M.apply_status_effect(/datum/status_effect/chem/SDGF/candidates)
/datum/status_effect/chem/SDGF/candidates/candies = new /datum/status_effect/chem/SDGF/candidates
///datum/status_effect/chem/SDGF/candidates/candies = M.apply_status_effect(/datum/status_effect/chem/SDGF/candidates)
//candies = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies
message_admins("Attempting to poll")*/
//Main SDGF chemical
/datum/reagent/fermi/SDGF/on_mob_life(mob/living/carbon/M) //Clones user, then puts a ghost in them! If that fails, makes a braindead clone.
//Setup clone
switch(current_cycle)
if(1)
for(var/mob/dead/observer/G in GLOB.player_list)
group += G
for(var/m in group)
var/mob/W = m
message_admins("Attempting to poll")
showCandidatePollWindow(M, 190, "Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you.", result, null, current_cycle, TRUE)
if(19)
for(var/mob/W in result)
if(!W.key || !W.client)
result -= W
candies = result
startHunger = M.nutrition
if(pollStarted == FALSE)
pollStarted = TRUE
candies = pollGhostCandidates("Do you want to play as a clone and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you.")
if(20 to INFINITY)
message_admins("Number of candidates [LAZYLEN(candies)]")
if(LAZYLEN(candies) && src.playerClone == FALSE) //If there's candidates, clone the person and put them in there!
message_admins("Candidate found!")
to_chat(M, "<span class='warning'>The cells reach a critical micelle concentration, nucleating rapidly within your body!</span>")
//var/typepath = owner.type
//clone = new typepath(owner.loc)
var/typepath = M.type
var/mob/living/carbon/fermi_Gclone = new typepath(M.loc)
var/mob/living/carbon/human/fermi_Gclone = new typepath(M.loc)
//var/mob/living/carbon/SM = owner
//var/mob/living/carbon/M = M
var/mob/living/carbon/SM = fermi_Gclone
var/mob/living/carbon/human/SM = fermi_Gclone
if(istype(SM) && istype(M))
SM.real_name = M.real_name
M.dna.transfer_identity(SM)
@@ -261,6 +269,8 @@
SM.key = C.key
SM.mind.enslave_mind_to_creator(M)
//If they're a zombie, they can try to negate it with this.
//I seriously wonder if anyone will ever use this function.
if(M.getorganslot(ORGAN_SLOT_ZOMBIE))//sure, it "treats" it, but "you've" still got it. Doesn't always work as well; needs a ghost.
var/obj/item/organ/zombie_infection/ZI = M.getorganslot(ORGAN_SLOT_ZOMBIE)
ZI.Remove(M)
@@ -269,62 +279,96 @@
//SM.sentience_act()
to_chat(SM, "<span class='warning'>You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with yourself, or rather, your original self.</span>")
to_chat(SM, "<span class='userdanger'>While you find your newfound existence strange, you share the same memories as [M.real_name]. [pick("However, You find yourself indifferent to the goals you previously had, and take more interest in your newfound independence, but still have an indescribable care for the safety of your original", "Your mind has not deviated from the tasks you set out to do, and now that there's two of you the tasks should be much easier.")]</span>")
to_chat(M, "<span class='notice'>You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with yourself.</span>")
to_chat(M, "<span class='warning'>You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with yourself.</span>")
M.visible_message("[M] suddenly shudders, and splits into two identical twins!")
SM.copy_known_languages_from(M, FALSE)
playerClone = TRUE
M.next_move_modifier = 1
M.nutrition = 150
M.nutrition -= 500
//reaction_mob(SM, )I forget what this is for
//Damage the clone
SM.blood_volume = BLOOD_VOLUME_NORMAL/2
SM.adjustCloneLoss(80, 0)
SM.setBrainLoss(40)
SM.nutrition = startHunger/2
//var/datum/reagents/SMR = SM
///datum/reagents
//var/mob/living/carbon/human has a holder, carbon does not
// You need to add to a holder.
// reagentS not reagent (?)
//SM.create_reagents()
//Really hacky way to deal with this stupid problem I have
SM.reagents.add_reagent("SDGFheal", volume)
//holder.add_reagent("SDGFheal", volume)
holder.remove_reagent(src.id, 999)
//SMR = locate(/datum/reagents in SM)
//holder.trans_to(SMR, volume)
//Give the new clone an idea of their character
//SHOULD print last 5 messages said by the original to the clones chatbox
var/list/say_log = M.logging[LOG_SAY]
if(LAZYLEN(say_log) > 5)
var/recent_speech = say_log.Copy(say_log.len+5,0) //0 so len-LING_ARS+1 to end of list
else
for(var/spoken_memory in recent_speech)
to_chat(SM, spoken_memory)
return
//BALANCE: should I make them a pacifist, or give them some cellular damage or weaknesses?
//after_success(user, SM)
//qdel(src)
else //No candidates leads to two outcomes; if there's already a braincless clone, it heals the user, as well as being a rare souce of clone healing (thematic!).
else if(src.playerClone == FALSE) //No candidates leads to two outcomes; if there's already a braincless clone, it heals the user, as well as being a rare souce of clone healing (thematic!).
message_admins("Failed to find clone Candidate")
src.unitCheck = TRUE
if(M.has_status_effect(/datum/status_effect/chem/SGDF)) // Heal the user if they went to all this trouble to make it and can't get a clone, the poor fellow.
to_chat(M, "<span class='notice'>The cells fail to catalyse around a nucleation event, instead merging with your cells.</span>") //This stuff is hard enough to make to rob a user of some benefit. Shouldn't replace Rezadone as it requires the user to not only risk making a player controlled clone, but also requires them to have split in two (which also requires 30u of SGDF).
M.adjustCloneLoss(-2, 0)
M.adjustBruteLoss(-2, 0)
M.adjustFireLoss(-2, 0)
M.heal_bodypart_damage(1,1)
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
switch(current_cycle)
if(21)
to_chat(M, "<span class='notice'>The cells fail to catalyse around a nucleation event, instead merging with your cells.</span>") //This stuff is hard enough to make to rob a user of some benefit. Shouldn't replace Rezadone as it requires the user to not only risk making a player controlled clone, but also requires them to have split in two (which also requires 30u of SGDF).
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
if(22 to INFINITY)
M.adjustCloneLoss(-1, 0)
M.adjustBruteLoss(-1, 0)
M.adjustFireLoss(-1, 0)
M.heal_bodypart_damage(1,1)
else //If there's no ghosts, but they've made a large amount, then proceed to make flavourful clone, where you become fat and useless until you split.
switch(current_cycle)
if(10)
if(21)
to_chat(M, "<span class='notice'>You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.</span>")
if(11 to 19)
if(22 to 29)
M.nutrition = M.nutrition + (M.nutrition/10)
if(20)
if(30)
to_chat(M, "<span class='notice'>You feel the synethic cells grow and expand within yourself, bloating your body outwards.</span>")
if(21 to 39)
if(31 to 49)
M.nutrition = M.nutrition + (M.nutrition/5)
if(40)
if(50)
to_chat(M, "<span class='notice'>The synthetic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.</span>")
M.next_move_modifier = 4//If this makes you fast then please fix it, it should make you slow!!
M.next_move_modifier += 4//If this makes you fast then please fix it, it should make you slow!!
//candidates = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies
if(41 to 69)
if(51 to 79)
M.nutrition = M.nutrition + (M.nutrition/2)
if(70)
if(80)
to_chat(M, "<span class='notice'>The cells begin to precipitate outwards of your body, you feel like you'll split soon...</span>")
if (M.nutrition < 20000)
M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI
if(76)//Upon splitting, you get really hungry and are capable again. Deletes the chem after you're done.
if(86)//Upon splitting, you get really hungry and are capable again. Deletes the chem after you're done.
M.nutrition = 15//YOU BEST BE EATTING AFTER THIS YOU CUTIE
M.next_move_modifier = 1
M.next_move_modifier -= 4
to_chat(M, "<span class='notice'>Your body splits away from the cell clone of yourself, leaving you with a drained and hollow feeling inside.</span>")
M.apply_status_effect(/datum/status_effect/chem/SGDF)
if(77 to INFINITY)
holder.remove_reagent("SGDF", 1)//removes SGDF on completion.
if(87 to INFINITY)
holder.remove_reagent(src.id, 1)//removes SGDF on completion.
message_admins("Purging SGDF [volume]")
message_admins("Growth nucleation occuring (SDGF), step [current_cycle] of 77")
..()
/datum/reagent/fermi/SDGF/on_mob_delete(mob/living/M) //When the chem is removed, a few things can happen.
/datum/reagent/fermi/SDGF/on_mob_delete(mob/living/M) //When the chem is removed, a few things can happen, mostly consolation prizes.
pollStarted = FALSE
if (playerClone == TRUE)//If the player made a clone with it, then thats all they get.
playerClone = FALSE
return
@@ -340,109 +384,506 @@
M.nutrition += 250
else if (src.unitCheck == TRUE && !M.has_status_effect(/datum/status_effect/chem/SGDF))// If they're ingested a little bit (10u minimum), then give them a little healing.
src.unitCheck = FALSE
to_chat(M, "<span class='notice'>the cells fail to hold enough mass to generate a clone, instead diffusing into your system instead. you can fee</span>")
to_chat(M, "<span class='notice'>the cells fail to hold enough mass to generate a clone, instead diffusing into your system.</span>")
M.adjustBruteLoss(-10, 0)
M.adjustFireLoss(-10, 0)
M.blood_volume += 100
M.next_move_modifier = 1
if (M.nutrition < 1500)
M.nutrition += 500
//If the reaction explodes
/*
/datum/reagent/fermi/SDGF/FermiExplode(turf/open/T)//Spawns an angery teratoma!! Spooky..! be careful!! TODO: Add teratoma slime subspecies
//var/mob/living/simple_animal/slime/S = new(get_turf(location_created),"grey")
var/mob/living/simple_animal/slime/S = new(T,"grey")//should work, in theory
S.damage_coeff = list(BRUTE = 0.9 , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)//I dunno how slimes work cause fire is burny
S.name = "Living teratoma"
S.real_name = "Living teratoma"//horrifying!!
S.rabid = 1//Make them an angery boi, grr grr
to_chat("<span class='notice'>The cells clump up into a horrifying tumour.</span>")
*/
//Unobtainable, used in clone spawn.
/datum/reagent/fermi/SDGFheal
name = "synthetic-derived growth factor"
id = "SDGFheal"
metabolization_rate = 1
/datum/reagent/fermi/SDGFheal/on_mob_life(mob/living/carbon/M)//Used to heal the clone after splitting, the clone spawns damaged. (i.e. insentivies players to make more than required, so their clone doesn't have to be treated)
if(M.blood_volume < BLOOD_VOLUME_NORMAL)
M.blood_volume += 10
M.adjustCloneLoss(-2, 0)
M.setBrainLoss(-1)
M.nutrition += 10
..()
//Unobtainable, used if SDGF is impure but not too impure
/datum/reagent/fermi/SDGFtox
name = "synthetic-derived growth factor"
id = "SDGFtox"
description = "A chem that makes Fermis angry at you if you're reading this, how did you get this???"
metabolization_rate = 1
/datum/reagent/fermi/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good)
M.blood_volume -= 10
M.adjustCloneLoss(2, 0)
..()
//Fail state of SDGF
/datum/reagent/fermi/SDZF
name = "synthetic-derived zombie factor"
name = "synthetic-derived growth factor"
id = "SDZF"
description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. This message should never appear, how did you manage to get a hold of this?"
color = "#60A584" // rgb: 96, 0, 255
metabolization_rate = 0.25 * REAGENTS_METABOLISM
var/fermi_Zombie
metabolization_rate = 0.5 * REAGENTS_METABOLISM
var/startHunger
/datum/reagent/fermi/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead.
message_admins("SGZF ingested")
switch(current_cycle)//Pretends to be normal
if(10)
to_chat(M, "<span class='notice'>You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.</span>")
if(11 to 19)
M.nutrition = M.nutrition + (M.nutrition/10)
if(20)
to_chat(M, "<span class='notice'>You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.</span>")
startHunger = M.nutrition
if(21 to 29)
M.nutrition = M.nutrition + (M.nutrition/10)
if(30)
to_chat(M, "<span class='notice'>You feel the synethic cells grow and expand within yourself, bloating your body outwards.</span>")
if(21 to 39)
if(31 to 49)
M.nutrition = M.nutrition + (M.nutrition/5)
if(40)
if(50)
to_chat(M, "<span class='notice'>The synethic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.</span>")
M.next_move_modifier = 4//If this makes you fast then please fix it, it should make you slow!!
if(41 to 63)
if(51 to 73)
M.nutrition = M.nutrition + (M.nutrition/2)
if(64)
if(74)
to_chat(M, "<span class='notice'>The cells begin to precipitate outwards of your body, but... something is wrong, the sythetic cells are beginnning to rot...</span>")
if (M.nutrition < 20000)
if (M.nutrition < 20000) //whoever knows the maxcap, please let me know, this seems a bit low.
M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI
if(65 to 75)
if(75 to 85)
M.adjustToxLoss(1, 0)// the warning!
if(76)
if(86)
if (!holder.has_reagent("pen_acid"))//Counterplay is pent.)
message_admins("Zombie spawned at [M.loc]")
M.nutrition -= 18500//YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE
M.nutrition = startHunger - 500//YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE
M.next_move_modifier = 1
to_chat(M, "<span class='warning'>Your body splits away from the cell clone of yourself, your attempted clone birthing itself violently from you as it begins to shamble around, a terrifying abomination of science.</span>")
M.visible_message("[M] suddenly shudders, and splits into a funky smelling copy of themselves!")
M.emote("scream")
M.adjustToxLoss(30, 0)
//fermi_Zombie = new typepath(M.loc)
var/mob/living/simple_animal/hostile/zombie/ZI = new(get_turf(M.loc))
ZI.damage_coeff = list(BRUTE = ((1 / volume)**0.25) , BURN = ((1 / volume)**0.1), TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
ZI.real_name = M.real_name//Give your offspring a big old kiss.
ZI.name = M.real_name
ZI.desc = "[M]'s clone, gone horribly wrong."
ZI.zombiejob = null
//ZI.updateappearance(mutcolor_update=1)
holder.remove_reagent("SGZF", 50)
else
to_chat(M, "<span class='notice'>The pentetic acid seems to have stopped the decay for now, clumping up the cells into a horrifying tumour.</span>")
if(77 to INFINITY)//purges chemical fast, producing a "slime" for each one. Said slime is weak to fire.
M.nutrition -= 100
var/mob/living/simple_animal/slime/S = new(get_turf(M.loc),"grey")
S.damage_coeff = list(BRUTE = ((1 / volume)**0.1) , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
S.name = "Living teratoma"
S.real_name = "Living teratoma"
//S.updateappearance(mutcolor_update=1)
holder.remove_reagent("SGZF", 50)
M.adjustToxLoss(10, 0)
to_chat(M, "<span class='warning'>A large glob of the tumour suddenly splits itself from your body. You feel grossed out and slimey...</span>")
holder.remove_reagent(src.id, 20)
else//easier to deal with
to_chat(M, "<span class='notice'>The pentetic acid seems to have stopped the decay for now, clumping up the cells into a horrifying tumour!</span>")
M.nutrition = startHunger - 500
var/mob/living/simple_animal/slime/S = new(get_turf(M.loc),"grey") //TODO: replace slime as own simplemob/add tumour slime cores for science/chemistry interplay
S.damage_coeff = list(BRUTE = ((1 / volume)**0.1) , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
S.name = "Living teratoma"
S.real_name = "Living teratoma"//horrifying!!
S.rabid = 1//Make them an angery boi
//S.updateappearance(mutcolor_update=1)
holder.remove_reagent(src.id, 20)
to_chat(M, "<span class='warning'>A large glob of the tumour suddenly splits itself from your body. You feel grossed out and slimey...</span>")
if(87 to INFINITY)//purges chemical fast, producing a "slime" for each one. Said slime is weak to fire. TODO: turn tumour slime into real variant.
M.adjustToxLoss(1, 0)
message_admins("Growth nucleation occuring (SDGF), step [current_cycle] of 20")
..()
//Breast englargement
//breast englargement
//Honestly the most requested chems
//I'm not a very kinky person, sorry if it's not great
//I tried to make it interesting..!!
/datum/reagent/fermi/BElarger
name = "Sucubus Draft"
name = "Sucubus milk"
id = "BEenlager"
description = "A volatile collodial mixture derived from milk that encourages mammary production via a potent estrogen mix."
color = "#60A584" // rgb: 96, 0, 255
color = "#E60584" // rgb: 96, 0, 255
taste_description = "a milky ice cream like flavour."
overdose_threshold = 12
metabolization_rate = 0.5
var/mob/living/carbon/human/H
/datum/reagent/fermi/BElarger/on_mob_add(mob/living/carbon/M)
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/breasts/B = H.getorganslot("breasts")
if(!B)
return
var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5)
B.prev_size = B.size
B.cached_size = sizeConv[B.size]
message_admins("init B size: [B.size], prev: [B.prev_size], cache = [B.cached_size], raw: [sizeConv[B.size]]")
/datum/reagent/fermi/BElarger/on_mob_life(mob/living/carbon/M) //Increases breast size
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
if(!B) //If they don't have breasts, give them breasts.
message_admins("No breasts found!")
var/obj/item/organ/genital/breasts/nB = new
nB.Insert(M)
if(nB)
if(M.dna.species.use_skintones && M.dna.features["genitals_use_skintone"])
nB.color = skintone2hex(H.skin_tone)
else if(M.dna.features["breasts_color"])
nB.color = "#[M.dna.features["breasts_color"]]"
else
nB.color = skintone2hex(H.skin_tone)
nB.size = "flat"
nB.cached_size = 0
nB.prev_size = 0
to_chat(M, "<span class='warning'>Your chest feels warm, tingling with newfound sensitivity.</b></span>")
M.reagents.remove_reagent(src.id, 5)
B = nB
//If they have them, increase size. If size is comically big, limit movement and rip clothes.
//message_admins("Breast size: [B.size], [B.cached_size], [holder]")
B.cached_size = B.cached_size + 0.1
if (B.cached_size >= 8.5 && B.cached_size < 9)
if(H.w_uniform || H.wear_suit)
var/target = M.get_bodypart(BODY_ZONE_CHEST)
to_chat(M, "<span class='warning'>Your breasts begin to strain against your clothes tightly!</b></span>")
M.adjustOxyLoss(10, 0)
M.apply_damage(2, BRUTE, target)
B.update()
..()
/datum/reagent/fermi/BElarger/overdose_process(mob/living/carbon/M) //Turns you into a female if male and ODing, doesn't touch nonbinary and object genders.
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
/datum/reagent/fermi/BElarger/overdose_start(mob/living/M) //Turns you into a female if male and ODing
if(M.gender == MALE)
M.gender = FEMALE
M.visible_message("<span class='boldnotice'>[M] suddenly looks more feminine!</span>", "<span class='boldwarning'>You suddenly feel more feminine!</span>")
if(P)
P.length = P.length - 0.1
message_admins("lewdsnek size: [P.size], [P.cached_length], [holder]")
P.update()
if(T)
T.Remove(M)
if(!V)
var/obj/item/organ/genital/vagina/nV = new
nV.Insert(M)
V = nV
if(!W)
var/obj/item/organ/genital/womb/nW = new
nW.Insert(M)
W = nW
..()
//TODO: failing the reaction creates a penis instead.
/datum/reagent/fermi/PElarger // Due to popular demand...!
name = "Incubus draft"
id = "PElarger"
description = "A volatile collodial mixture derived from various masculine solutions that encourages a larger gentleman's package via a potent testosterone mix, formula derived from a collaboration from Fermicem corp and Doctor Ronald Hyatt, who is well known for his phallus palace." //The toxic masculinity thing is a joke because I thought it would be funny to include it in the reagents, but I don't think many would find it funny?
color = "#888888" // This is greyish..?
taste_description = "chinese dragon powder"
overdose_threshold = 12 //ODing makes you male and removes female genitals
metabolization_rate = 0.5
//var/mob/living/carbon/M
//var/mob/living/carbon/human/species/S
/*
var/obj/item/organ/genital/penis/P
var/obj/item/organ/genital/testicles/T
var/obj/item/organ/genital/vagina/V
var/obj/item/organ/genital/womb/W
var/obj/item/organ/genital/breasts/B
*/
var/mob/living/carbon/human/H
/datum/reagent/fermi/PElarger/on_mob_life(mob/living/carbon/M) //Increases penis size, 5u = +1 inch.
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
if(!P)
message_admins("No penis found!")//They do have a preponderance for escapism, or so I've heard.
var/obj/item/organ/genital/penis/nP = new
nP.Insert(M)
if(nP)
nP.length = 0.2
to_chat(M, "<span class='warning'>Your groin feels warm, as you feel a newly forming bulge down below.</b></span>")//OwO
nP.cached_length = 0.1
nP.prev_size = 0.1
M.reagents.remove_reagent(src.id, 5)
P = nP
P.cached_length = P.cached_length + 0.1
if (P.cached_length >= 20.5 && P.cached_length < 21) //too low? Yes, 20 is the max
if(H.w_uniform || H.wear_suit)
var/target = M.get_bodypart(BODY_ZONE_CHEST)
to_chat(M, "<span class='warning'>Your cock begin to strain against your clothes tightly!</b></span>")
M.apply_damage(5, BRUTE, target)
P.update()
..()
/datum/reagent/fermi/PElarger/overdose_process(mob/living/carbon/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders.
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
message_admins("PE Breast status: [B]")
if(M.gender == FEMALE)
M.gender = MALE
M.visible_message("<span class='boldnotice'>[M] suddenly looks more masculine!</span>", "<span class='boldwarning'>You suddenly feel more masculine!</span>")
if(B)
B.cached_size = B.cached_size - 0.1
message_admins("Breast size: [B.size], [B.cached_size], [holder]")
B.update()
if(V)
V.Remove(M)
if(W)
W.Remove(M)
if(!T)
var/obj/item/organ/genital/testicles/nT = new
nT.Insert(M)
T = nT
..()
/datum/reagent/fermi/astral // Gives you the ability to astral project for a moment!
name = "Astrogen"
id = "astral"
description = "An opalescent murky liquid that is said to distort your soul from your being."
color = "#A080H4" // rgb: , 0, 255
taste_description = "velvety brambles"
metabolization_rate = 0//Removal is exponential, see code
overdose_threshold = 20
addiction_threshold = 30
addiction_stage1_end = 9999//Should never end.
var/mob/living/carbon/origin
var/mob/living/simple_animal/hostile/retaliate/ghost/G = null
var/ODing = FALSE
//var/Svol = volume
/datum/reagent/fermi/astral/on_mob_life(mob/living/M) // Gives you the ability to astral project for a moment!
M.alpha = 255//Reset addiction
switch(current_cycle)
if(0)//Require a minimum
//var/mob/living/carbon/H = M
//M.alpha = 255
origin = M
if (G == null)
G = new(get_turf(M.loc))
G.attacktext = "raises the hairs on the neck of"
G.response_harm = "disrupts the concentration of"
G.response_disarm = "wafts"
G.loot = null
G.maxHealth = 5
G.health = 5
G.melee_damage_lower = 0
G.melee_damage_upper = 0
G.deathmessage = "disappears as if it was never really there to begin with"
G.incorporeal_move = 1
G.alpha = 35
G.name = "[M]'s astral projection"
M.mind.transfer_to(G)
holder.remove_reagent(src.id, current_cycle, FALSE)
..()
/datum/reagent/fermi/astral/on_mob_delete(mob/living/carbon/M)
G.mind.transfer_to(origin)
qdel(G)
if(ODing == TRUE)
M.Sleeping(10*volume, 0)
ODing = FALSE
..()
/datum/reagent/fermi/astral/overdose_process(mob/living/carbon/M)
ODing = TRUE
if (!G == null)
if(prob(70))
to_chat(M, "<span class='warning'>The high conentration of Astrogen in your blood causes you to lapse your concentration for a moment, bringing your projection back to yourself!</b></span>")
do_teleport(G, M.loc)
..()
//Okay so, this might seem a bit too good, but my counterargument is that it'll likely take all round to eventually kill you this way, then you have to be revived without a body. It takes approximately 60-80 minutes to die from this.
/datum/reagent/fermi/astral/addiction_act_stage1(mob/living/carbon/M)
if(prob(65))
M.alpha = M.alpha - 1
switch(M.alpha)
if(245)
to_chat(M, "<span class='warning'>You notice your body starting to disappear, maybe you took too much Astrogen...?</b></span>")
M.alpha = M.alpha - 1
if(220)
to_chat(M, "<span class='notice'>Your addiction is only getting worse as your body disappears. Maybe you should get some more, and fast?</b></span>")
M.alpha = M.alpha - 1
if(180)
to_chat(M, "<span class='notice'>You're starting to get scared as more and more of your body and consciousness begins to fade.</b></span>")
M.alpha = M.alpha - 1
if(120)
to_chat(M, "<span class='notice'>As you lose more and more of yourself, you start to think that maybe shedding your mortality isn't too bad.</b></span>")
M.alpha = M.alpha - 1
if(100)
to_chat(M, "<span class='notice'>You feel a substantial part of your soul flake off into the ethereal world, rendering yourself unclonable.</b></span>")
M.alpha = M.alpha - 1
M.add_trait(TRAIT_NOCLONE)
if(80)
to_chat(M, "<span class='notice'>You feel a thrill shoot through your body as what's left of your mind contemplates the forthcoming oblivion.</b></span>")
M.alpha = M.alpha - 1
if(45)
to_chat(M, "<span class='warning'>The last vestiges of your mind eagerly await your imminent annihilation.</b></span>")
M.alpha = M.alpha - 1
if(0 to 30)
to_chat(M, "<span class='warning'>Your body disperses from existence, as you become one with the universe.</b></span>")
to_chat(M, "<span class='userdanger'>As your body disappears, your consciousness doesn't. Should you find a way back into the mortal coil, your memories of the afterlife remain with you. (At the cost of staying in character while dead.)</span>")//Legalised IC OOK? I have a suspicion this won't make it past the review. At least it'll be presented as a neat idea! If this is unacceptable how about the player can retain living memories across lives if they die in this way only.
M.visible_message("[M] suddenly disappears, their body evaporating from existence, freeing [M] from their mortal coil.")
qdel(M) //Approx 60minutes till death from initial addiction
..()
/datum/reagent/fermi/enthrall
name = "MKUltra"
id = "enthral"
description = "Need a description."
color = "#A080H4" // rgb: , 0, 255
taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses"
//metabolization_rate = 0.5
overdose_threshold = 100 //If this is too easy to get 100u of this, then double it please.
//addiction_threshold = 30
//addiction_stage1_end = 9999//Should never end.
var/creatorID //ckey
var/creatorGender
var/creatorName
var/mob/living/creator
/datum/reagent/fermi/enthrall/on_mob_add(mob/living/carbon/M)
..()
if(!creatorID)
CRASH("Something went wrong in enthral creation")
else if(M.key == creatorID && creatorName == M.real_name) //same name AND same player - same instance of the player. (should work for clones?)
var/obj/item/organ/vocal_cords/Vc = M.getorganslot(ORGAN_SLOT_VOICE)
var/obj/item/organ/vocal_cords/nVc = new /obj/item/organ/vocal_cords/velvet
Vc.Remove(M)
nVc.Insert(M)
qdel(Vc)
to_chat(M, "<span class='notice'><i>You feel your vocal chords tingle as your voice comes out in a more sultry tone.</span>")
creator = M
else
M.apply_status_effect(/datum/status_effect/chem/enthrall)
var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall)
E.enthrallID = creatorID
E.enthrallGender = creatorGender
E.master = creator
/datum/reagent/fermi/enthrall/on_mob_life(mob/living/carbon/M)
var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall)
E.enthrallTally += 1
M.adjustBrainLoss(0.1)
..()
/datum/reagent/fermi/enthrall/overdose_start(mob/living/carbon/M)
M.add_trait(TRAIT_PACIFISM, "MKUltra")
var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall)
if (!M.has_status_effect(/datum/status_effect/chem/enthrall))
M.apply_status_effect(/datum/status_effect/chem/enthrall)
E.enthrallID = creatorID
E.enthrallGender = creatorGender
E.master = creator
to_chat(M, "<span class='warning'><i>Your mind shatters under the volume of the mild altering chem inside of you, breaking all will and thought completely. Instead the only force driving you now is the instinctual desire to obey and follow [creatorName].</i></span>")
M.slurring = 100
M.confused = 100
E.phase = 4
E.mental_capacity = 0
E.customTriggers = list()
/datum/reagent/fermi/enthrall/overdose_process(mob/living/carbon/M)
M.adjustBrainLoss(0.2)
..()
//Requires player to be within vicinity of creator
//bonuses to mood
//gives creator a silver(velvet?) tongue
//Addiction is applied when creator is out of viewer
//
///////////////////////////////////////////////////////////////////////////////////////////////////
/datum/reagent/fermi/furranium
name = "Furranium"
id = "furranium"
description = "OwO whats this?"
color = "#H04044" // rgb: , 0, 255
taste_description = "dewicious degenyewacy"
/datum/reagent/fermi/furranium/on_mob_life(mob/living/carbon/M)
switch(current_cycle)
if(1 to 9)
if(prob(20))
to_chat(M, "<span class='notice'>Your tongue feels... fluffy</span>")
if(10 to 20)
if(prob(20))
to_chat(M, "You find yourself unable to supress the desire to meow!")
M.emote("nya")
if(prob(20))
to_chat(M, "You find yourself unable to supress the desire to howl!")
M.emote("awoo")
if(prob(20))
var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers
//for(var/victim in seen)
to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]")
if(21)
var/obj/item/organ/tongue/T = M.getorganslot(ORGAN_SLOT_TONGUE)
var/obj/item/organ/tongue/nT = new /obj/item/organ/tongue/OwO
T.Remove(M)
nT.Insert(M)
qdel(T)
if(22 to INFINITY)
if(prob(20))
to_chat(M, "You find yourself unable to supress the desire to meow!")
M.emote("nya")
if(prob(20))
to_chat(M, "You find yourself unable to supress the desire to howl!")
M.emote("awoo")
if(prob(20))
var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers
//for(var/victim in seen)
to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]")
..()
/*
/mob/living/simple_animal/hostile/retaliate/ghost
incorporeal_move = 1
name
alpha = 20
reduce viewrange?
*/
/*
//Nanite removal
//Writen by Trilby!!
/datum/reagent/fermi/naninte_b_gone
name = "Naninte bain"
id = "naninte_b_gone"
description = "A rather simple toxin to small nano machines that will kill them off at a rapid rate well in system."
color = "#5a7267" // rgb: 90, 114, 103
overdose_threshold = 25
v/component/nanites/nan
/datum/reagent/fermi/naninte_b_gone/on_mob_life(mob/living/carbon/C)
if(C./datum/component/nanites)
regen_rate = -5.0
else
var/component/nanites/nane = C.GetComponent(/component/nanites)
if(isnull(nane))
return
nane.regen_rate = -5.0
/datum/reagent/fermi/naninte_b_gone/overdose_start(mob/living/carbon/C)
if(C./datum/component/nanites)
regen_rate = -7.5
else
var/component/nanites/nane = C.GetComponent(/component/nanites)
if(isnull(nane))
return
nane.regen_rate = -7.5
*/
/*
_________________________________________
||Fermichem toxic / impure chems here. ||
|| ||
||_______________________________________||
*/
@@ -23,6 +23,11 @@
FermiExplode = FALSE //If the chemical explodes in a special way
ImpureChem = "toxin" //What chemical is produced with an inpure reaction
/datum/chemical_reaction/eigenstate/on_reaction(datum/reagents/holder)
var/location = get_turf(holder.my_atom)
var/datum/reagent/fermi/eigenstate/E = locate(/datum/reagent/fermi/eigenstate) in holder.reagent_list
E.location_created = location
//serum
/datum/chemical_reaction/SDGF
name = "synthetic-derived growth factor"
@@ -31,22 +36,23 @@
required_reagents = list("plasma" = 1, "stable_plasma" = 1, "sugar" = 1)
//required_reagents = list("stable_plasma" = 5, "slimejelly" = 5, "synthflesh" = 10, "blood" = 10)
//FermiChem vars:
OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions
OptimalTempMax = 500 // Upper end for above
ExplodeTemp = 550 //Temperature at which reaction explodes
OptimalpHMin = 4 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
OptimalpHMax = 9.5 // Higest value for above
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
CurveSharppH = 2 // How sharp the pH exponential curve is (to the power of value)
ThermicConstant = 20 //Temperature change per 1u produced
HIonRelease = 0.01 //pH change per 1u reaction
RateUpLim = 5 //Optimal/max rate possible if all conditions are perfect
FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE //If the chemical explodes in a special way
ImpureChem = "toxin" //What chemical is produced with an inpure reaction
OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions
OptimalTempMax = 500 // Upper end for above
ExplodeTemp = 550 // Temperature at which reaction explodes
OptimalpHMin = 4 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
OptimalpHMax = 9.5 // Higest value for above
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
CurveSharppH = 2 // How sharp the pH exponential curve is (to the power of value)
ThermicConstant = 20 // Temperature change per 1u produced
HIonRelease = 0.01 // pH change per 1u reaction
RateUpLim = 5 // Optimal/max rate possible if all conditions are perfect
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE // If the chemical explodes in a special way
ImpureChem = "SDGFTox" // What chemical is metabolised with an inpure reaction
InverseChemVal = 0.5 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
InverseChem = "SDZF" // What chem is metabolised when purity is below InverseChemVal
/datum/chemical_reaction/BElarger
name = ""
@@ -90,3 +96,43 @@
FermiChem = TRUE
FermiExplode = FALSE
ImpureChem = "carpotoxin"
/datum/chemical_reaction/enthral
name = "need a name"
id = "enthral"
results = list("enthral" = 3)
required_reagents = list("plasma" = 1, "stable_plasma" = 1, "sugar" = 1)
required_catalysts = list("blood" = 1)
//required_reagents = list("stable_plasma" = 5, "slimejelly" = 5, "synthflesh" = 10, "blood" = 10)
//FermiChem vars:
OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions
OptimalTempMax = 500 // Upper end for above
ExplodeTemp = 550 // Temperature at which reaction explodes
OptimalpHMin = 4 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
OptimalpHMax = 9.5 // Higest value for above
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
CurveSharppH = 2 // How sharp the pH exponential curve is (to the power of value)
ThermicConstant = 20 // Temperature change per 1u produced
HIonRelease = 0.01 // pH change per 1u reaction
RateUpLim = 5 // Optimal/max rate possible if all conditions are perfect
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE // If the chemical explodes in a special way
//ImpureChem = "SDGFTox" // What chemical is metabolised with an inpure reaction
//InverseChemVal = 0.5 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
//InverseChem = "SDZF" // What chem is metabolised when purity is below InverseChemVal
/datum/chemical_reaction/enthral/on_reaction(datum/reagents/holder)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in holder.reagent_list
if (B.["gender"] == "female")
E.creatorGender = "Mistress"
else
E.creatorGender = "Master"
E.creatorName = B.["real_name"]
E.creatorID = B.["ckey"]
var/mob/living/creator = holder
E.creator = creator
//var/enthrallID = B.get_blood_data()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 B

After

Width:  |  Height:  |  Size: 1.6 KiB

+1
View File
@@ -274,6 +274,7 @@
#include "code\controllers\subsystem\vore.dm"
#include "code\controllers\subsystem\vote.dm"
#include "code\controllers\subsystem\weather.dm"
#include "code\controllers\subsystem\processing\chemistry.dm"
#include "code\controllers\subsystem\processing\circuit.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fields.dm"