Merge branch 'master' into Updates-holder

This commit is contained in:
Fermi
2019-10-08 12:21:56 +01:00
259 changed files with 4782 additions and 1573 deletions
@@ -0,0 +1,23 @@
How to code fermichem reactions:
First off, probably read though the readme for standard reagent mechanisms, this builds on top of that.
#bitflags
for `datum/reagent/` you have the following options with `var/chemical_flags`:
```
REAGENT_DEAD_PROCESS calls on_mob_dead() if present in a dead body
REAGENT_DONOTSPLIT Do not split the chem at all during processing
REAGENT_ONLYINVERSE Only invert chem, no splitting
REAGENT_ONMOBMERGE Call on_mob_life proc when reagents are merging.
REAGENT_INVISIBLE Doesn't appear on handheld health analyzers.
REAGENT_FORCEONNEW Forces a on_new() call without a data overhead
REAGENT_SNEAKYNAME When inverted, the inverted chem uses the name of the original chem
REAGENT_SPLITRETAINVOL Retains initial volume of chem when splitting
```
for `datum/chemical_reaction/` under `var/clear_conversion`
```
REACTION_CLEAR_IMPURE Convert into impure/pure on reaction completion
REACTION_CLEAR_INVERSE Convert into inverse on reaction completion when purity is low enough
```
+25 -12
View File
@@ -466,7 +466,7 @@
if (C.FermiChem && !continue_reacting)
if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions.
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
var/datum/chemical_reaction/Ferm = selected_reaction
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion"))
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
@@ -541,7 +541,7 @@
return 0
/datum/reagents/process()
var/datum/chemical_reaction/fermi/C = fermiReactID
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
@@ -553,6 +553,11 @@
fermiEnd()
return
for(var/datum/reagent/P in C.required_catalysts)
if(!has_reagent(P.id))
fermiEnd()
return
if (!fermiIsReacting)
CRASH("Fermi has refused to stop reacting even though we asked her nicely.")
@@ -567,12 +572,12 @@
reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
if(round(reactedVol, CHEMICAL_QUANTISATION_LEVEL) == round(targetVol, CHEMICAL_QUANTISATION_LEVEL))
fermiEnd()
if(!reactedVol)
if(!reactedVol)//Maybe unnessicary.
fermiEnd()
return
/datum/reagents/proc/fermiEnd()
var/datum/chemical_reaction/fermi/C = fermiReactID
var/datum/chemical_reaction/C = fermiReactID
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
reactedVol = 0
@@ -584,7 +589,9 @@
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()
C.FermiFinish(src, my_atom)
C.FermiFinish(src, my_atom, reactedVol)
reactedVol = 0
targetVol = 0
handle_reactions()
update_total()
//Reaction sounds and words
@@ -594,7 +601,7 @@
to_chat(M, "<span class='notice'>[iconhtml] [C.mix_message]</span>")
/datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
var/datum/chemical_reaction/fermi/C = selected_reaction
var/datum/chemical_reaction/C = selected_reaction
var/deltaT = 0
var/deltapH = 0
var/stepChemAmmount = 0
@@ -678,7 +685,7 @@
STOP_PROCESSING(SSprocessing, src)
return
C.FermiCreate(src)//proc that calls when step is done
C.FermiCreate(src, addChemAmmount, purity)//proc that calls when step is done
//Apply pH changes and thermal output of reaction to beaker
chem_temp = round(cached_temp + (C.ThermicConstant * addChemAmmount))
@@ -702,7 +709,7 @@
return (reactedVol)
//Currently calculates it irrespective of required reagents at the start
/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder)
/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/C, holder)
var/list/cached_reagents = reagent_list
var/i = 0
var/cachedPurity
@@ -714,6 +721,14 @@
CRASH("No reactants found mid reaction for [fermiReactID]/[C], how it got here is beyond me. Beaker: [holder]")
return cachedPurity/i
/datum/reagents/proc/uncache_purity(id)
var/datum/reagent/R = has_reagent("[id]")
if(!R)
return
if(R.cached_purity == 1)
return
R.purity = R.cached_purity
/datum/reagents/proc/isolate_reagent(reagent)
var/list/cached_reagents = reagent_list
for(var/_reagent in cached_reagents)
@@ -888,10 +903,8 @@
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
if(isliving(my_atom))
if(R.OnMobMergeCheck)//Forces on_mob_add proc when a chem is merged
if(R.chemical_flags & REAGENT_ONMOBMERGE)//Forces on_mob_add proc when a chem is merged
R.on_mob_add(my_atom, amount)
//else
// R.on_merge(data, amount, my_atom, other_purity)
R.on_merge(data, amount, my_atom, other_purity)
if(!no_react)
handle_reactions()
@@ -909,7 +922,7 @@
if(data)
R.data = data
R.on_new(data)
if(R.addProc)//Allows on new without data overhead.
if(R.chemical_flags & REAGENT_FORCEONNEW)//Allows on new without data overhead.
R.on_new(pH) //Add more as desired.
@@ -405,7 +405,7 @@
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
@@ -432,7 +432,7 @@
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
@@ -201,6 +201,8 @@
B.reagents.add_reagent("blood", 20, data)
wait = TRUE
update_icon()
var/turf/source_turf = get_turf(src)
log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE
if("create_vaccine_bottle")
+75 -55
View File
@@ -32,20 +32,18 @@
var/addiction_stage3_end = 30
var/addiction_stage4_end = 40
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
var/self_consuming = FALSE
var/metabolizing = FALSE
var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
var/self_consuming = FALSE //I think this uhhh, makes weird stuff happen when metabolising, but... doesn't seem to do what I think, so I'm gonna leave it.
//Fermichem vars:
var/purity = 1 //How pure a chemical is from 0 - 1.
var/addProc = FALSE //If the chemical should force an on_new() call
var/turf/loc = null //Should be the creation location!
var/purity = 1 //How pure a chemical is from 0 - 1.
var/cached_purity = 1
var/turf/loc = null //Should be the creation location!
var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder.
var/SplitChem = FALSE //If the chem splits on metabolism
var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction
var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it.
var/DoNotSplit = FALSE // If impurity is handled within the main chem itself
var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging.
//var/SplitChem = FALSE //If the chem splits on metabolism
var/impure_chem // What chemical is metabolised with an inpure reaction
var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it.
var/metabolizing = FALSE
var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
@@ -75,28 +73,47 @@
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
//called when a mob processes chems when dead.
/datum/reagent/proc/on_mob_dead(mob/living/carbon/M)
if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase
return
current_cycle++
if(holder)
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
// Called when this reagent is first added to a mob
/datum/reagent/proc/on_mob_add(mob/living/L, amount)
if(SplitChem)
var/mob/living/carbon/M = L
if(!M)
return
if(purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if (purity == 1 || DoNotSplit == TRUE)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]")
return
else if (InverseChemVal > purity)//Turns all of a added reagent into the inverse chem
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [InverseChem]")
return
else
var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem
if(!iscarbon(L))
return
var/mob/living/carbon/M = L
if (purity == 1)
log_game("CHEM: [L] ckey: [L.key] has ingested [volume]u of [id]")
return
if(cached_purity == 1)
cached_purity = purity
else if(purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if(chemical_flags & REAGENT_DONOTSPLIT)
return
if ((inverse_chem_val > purity) && (inverse_chem))//Turns all of a added reagent into the inverse chem
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
if(R.chemical_flags & REAGENT_SNEAKYNAME)
R.name = name//Negative effects are hidden
if(R.chemical_flags & REAGENT_INVISIBLE)
R.chemical_flags |= (REAGENT_INVISIBLE)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [inverse_chem]")
return
else if (impure_chem)
var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem
if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, (impureVol), FALSE)
M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [ImpureChem]")
M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [impure_chem]")
return
// Called when this reagent is removed while inside a mob
@@ -120,31 +137,34 @@
// Called when two reagents of the same are mixing.
/datum/reagent/proc/on_merge(data, amount, mob/living/carbon/M, purity)
if(SplitChem)
if(!ishuman(M))
return
if (purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if (purity == 1 || DoNotSplit == TRUE)
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [id] in themselves")
return
else if (InverseChemVal > purity)
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1)
for(var/datum/reagent/fermi/R in M.reagents.reagent_list)
if(R.name == "")
R.name = name//Negative effects are hidden
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [InverseChem]")
return
else
var/impureVol = amount * (1 - purity)
if(!iscarbon(M))
return
if (purity == 1)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]")
return
cached_purity = purity //purity SHOULD be precalculated from the add_reagent, update cache.
if (purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if(chemical_flags & REAGENT_DONOTSPLIT)
return
if ((inverse_chem_val > purity) && (inverse_chem)) //INVERT
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
if(R.chemical_flags & REAGENT_SNEAKYNAME)
R.name = name//Negative effects are hidden
if(R.chemical_flags & REAGENT_INVISIBLE)
R.chemical_flags |= (REAGENT_INVISIBLE)
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [inverse_chem]")
return
else if (impure_chem) //SPLIT
var/impureVol = amount * (1 - purity)
if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, impureVol, FALSE)
M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1)
for(var/datum/reagent/fermi/R in M.reagents.reagent_list)
if(R.name == "")
R.name = name//Negative effects are hidden
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [ImpureChem]")
M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [impure_chem]")
return
/datum/reagent/proc/on_update(atom/A)
@@ -1383,10 +1383,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "neurotoxinglass"
glass_name = "Neurotoxin"
glass_desc = "A drink that is guaranteed to knock you silly."
SplitChem = TRUE
ImpureChem = "neuroweak"
InverseChemVal = 0 //Clear conversion
InverseChem = "neuroweak"
//SplitChem = TRUE
impure_chem = "neuroweak"
inverse_chem_val = 0.5 //Clear conversion
inverse_chem = "neuroweak"
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
@@ -1394,7 +1394,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
M.dizziness +=2
M.adjustBrainLoss(1*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 150)
if(prob(20) && !holder.has_reagent("neuroweak"))
M.adjustStaminaLoss(10)
M.drop_all_held_items()
@@ -1405,7 +1405,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
ADD_TRAIT(M, t, type)
M.adjustStaminaLoss(10)
if(current_cycle > 30)
M.adjustBrainLoss(2*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
if(current_cycle > 50 && prob(15))
if(!M.undergoing_cardiac_arrest() && M.can_heartattack())
M.set_heartattack(TRUE)
@@ -1431,13 +1431,13 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/neuroweak/on_mob_life(mob/living/carbon/M)
if(holder.has_reagent("neurotoxin"))
M.adjustBrainLoss(-1*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
M.reagents.remove_reagent("neurotoxin", 1.5 * REAGENTS_METABOLISM, FALSE)
if(holder.has_reagent("fentanyl"))
M.adjustBrainLoss(-1*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
M.reagents.remove_reagent("fentanyl", 0.75 * REAGENTS_METABOLISM, FALSE)
else
M.adjustBrainLoss(-0.5*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.5*REM, 150)
M.dizziness +=2
..()
@@ -80,14 +80,14 @@
. = 1
/datum/reagent/drug/crank/overdose_process(mob/living/M)
M.adjustBrainLoss(2*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
M.adjustToxLoss(2*REM, 0)
M.adjustBruteLoss(2*REM, 0)
..()
. = 1
/datum/reagent/drug/crank/addiction_act_stage1(mob/living/M)
M.adjustBrainLoss(5*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5*REM)
..()
/datum/reagent/drug/crank/addiction_act_stage2(mob/living/M)
@@ -101,7 +101,7 @@
. = 1
/datum/reagent/drug/crank/addiction_act_stage4(mob/living/M)
M.adjustBrainLoss(3*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM)
M.adjustToxLoss(5*REM, 0)
M.adjustBruteLoss(5*REM, 0)
..()
@@ -125,13 +125,13 @@
..()
/datum/reagent/drug/krokodil/overdose_process(mob/living/M)
M.adjustBrainLoss(0.25*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25*REM)
M.adjustToxLoss(0.25*REM, 0)
..()
. = 1
/datum/reagent/drug/krokodil/addiction_act_stage1(mob/living/M)
M.adjustBrainLoss(2*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
M.adjustToxLoss(2*REM, 0)
..()
. = 1
@@ -192,7 +192,7 @@
if(jitter)
M.Jitter(2)
if(brain_damage)
M.adjustBrainLoss(rand(1,4))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1,4))
M.heal_overall_damage(2, 2)
if(prob(5))
M.emote(pick("twitch", "shiver"))
@@ -210,7 +210,7 @@
M.drop_all_held_items()
..()
M.adjustToxLoss(1, 0)
M.adjustBrainLoss(pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
. = 1
/datum/reagent/drug/methamphetamine/addiction_act_stage1(mob/living/M)
@@ -289,7 +289,7 @@
if(prob(5))
to_chat(M, "<span class='notice'>[high_message]</span>")
M.adjustStaminaLoss(-5, 0)
M.adjustBrainLoss(4)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4)
M.hallucination += 5
if(M.canmove && !ismovableatom(M.loc))
step(M, pick(GLOB.cardinals))
@@ -314,7 +314,7 @@
for(var/i = 0, i < 8, i++)
step(M, pick(GLOB.cardinals))
M.Jitter(5)
M.adjustBrainLoss(10)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(20))
M.emote(pick("twitch","drool","moan"))
..()
@@ -326,7 +326,7 @@
step(M, pick(GLOB.cardinals))
M.Jitter(10)
M.Dizzy(10)
M.adjustBrainLoss(10)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(30))
M.emote(pick("twitch","drool","moan"))
..()
@@ -338,7 +338,7 @@
step(M, pick(GLOB.cardinals))
M.Jitter(15)
M.Dizzy(15)
M.adjustBrainLoss(10)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
@@ -351,7 +351,7 @@
M.Jitter(50)
M.Dizzy(50)
M.adjustToxLoss(5, 0)
M.adjustBrainLoss(10)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(50))
M.emote(pick("twitch","drool","moan"))
..()
@@ -401,7 +401,7 @@
M.jitteriness = 0
M.confused = 0
M.disgust = 0
M.adjustBrainLoss(0.2)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
..()
. = 1
@@ -418,7 +418,7 @@
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)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
..()
. = 1
@@ -490,7 +490,7 @@
H.dna.species.punchdamagehigh *= 0.2
/datum/reagent/drug/skooma/on_mob_life(mob/living/carbon/M)
M.adjustBrainLoss(1*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM)
M.adjustToxLoss(1*REM)
if(prob(10))
M.adjust_blurriness(2)
@@ -522,7 +522,7 @@
M.Dizzy(50)
M.adjust_blurriness(10)
if(prob(50)) //This proc will be called about 200 times and the adjustbrainloss() below only has to be called 40 times to kill. This will make surviving skooma addiction pretty rare without mannitol usage.
M.adjustBrainLoss(5)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
@@ -691,7 +691,7 @@
. = 1
if(prob(20))
M.losebreath += 4
M.adjustBrainLoss(2*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150)
M.adjustToxLoss(3*REM,0)
M.adjustStaminaLoss(10*REM,0)
M.blur_eyes(5)
@@ -0,0 +1,26 @@
//Reagents produced by metabolising/reacting fermichems inoptimally, i.e. inverse_chems or impure_chems
//Inverse = Splitting
//Invert = Whole conversion
/datum/reagent/impure
chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting
/datum/reagent/impure/fermiTox
name = "Chemical Isomers"
id = "fermiTox"
description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart."
data = "merge"
color = "FFFFFF"
can_synth = FALSE
var/potency = 1 //potency multiplies the volume when added.
//I'm concerned this is too weak, but I also don't want deathmixes.
//TODO: liver damage, 100+ heart
/datum/reagent/impure/fermiTox/on_mob_life(mob/living/carbon/C, method)
if(C.dna && istype(C.dna.species, /datum/species/jelly))
C.adjustToxLoss(-2)
else
C.adjustToxLoss(2)
..()
@@ -44,7 +44,7 @@
M.heal_bodypart_damage(5,5)
M.adjustToxLoss(-5, 0, TRUE)
M.hallucination = 0
M.setBrainLoss(0)
M.setOrganLoss(ORGAN_SLOT_BRAIN, 0)
REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT))
M.set_blurriness(0)
M.set_blindness(0)
@@ -64,6 +64,10 @@
if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume = (BLOOD_VOLUME_NORMAL*M.blood_ratio)
for(var/organ in M.internal_organs)
var/obj/item/organ/O = organ
O.setOrganDamage(0)
for(var/thing in M.diseases)
var/datum/disease/D = thing
if(D.severity == DISEASE_SEVERITY_POSITIVE)
@@ -852,10 +856,16 @@
if(M.notify_ghost_cloning(source = M))
spawn (100) //so the ghost has time to re-enter
return
else
M.adjustOxyLoss(-20, 0)
M.adjustToxLoss(-20, 0)
var/mob/living/carbon/H = M
for(var/organ in H.internal_organs)
var/obj/item/organ/O = organ
O.setOrganDamage(0)
M.updatehealth()
if(M.revive())
M.emote("gasp")
log_combat(M, M, "revived", src)
@@ -875,7 +885,7 @@
pH = 10.4
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C)
C.adjustBrainLoss(-2*REM)
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REM)
if(prob(10))
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
..()
@@ -1130,7 +1140,7 @@
M.adjustFireLoss(-5*REM, 0)
M.adjustOxyLoss(-15, 0)
M.adjustToxLoss(-5*REM, 0)
M.adjustBrainLoss(-15*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REM)
M.adjustCloneLoss(-3*REM, 0)
M.adjustStaminaLoss(-20*REM,0)
..()
@@ -1175,7 +1185,7 @@
M.adjustFireLoss(-3 * REM, 0)
M.adjustOxyLoss(-15 * REM, 0)
M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS
M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
M.adjustCloneLoss(-1 * REM, 0)
M.adjustStaminaLoss(-13 * REM, 0)
M.jitteriness = min(max(0, M.jitteriness + 3), 30)
@@ -1207,7 +1217,7 @@
if (M.hallucination >= 5)
M.hallucination -= 5
if(prob(20))
M.adjustBrainLoss(1*REM, 50)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 50)
M.adjustStaminaLoss(2.5*REM, 0)
..()
return TRUE
@@ -296,7 +296,7 @@
if(ishuman(M) && M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume += 3
else // Will deal about 90 damage when 50 units are thrown
M.adjustBrainLoss(3, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
M.adjustToxLoss(2, 0)
M.adjustFireLoss(2, 0)
M.adjustOxyLoss(2, 0)
@@ -315,7 +315,7 @@
M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire
M.adjustToxLoss(1, 0)
M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard?
M.adjustBrainLoss(5, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 150)
holder.remove_reagent(id, 1)
pH = 0.1
@@ -805,7 +805,7 @@
step(M, pick(GLOB.cardinals))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
M.adjustBrainLoss(1)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
..()
/datum/reagent/sulfur
@@ -1172,7 +1172,7 @@
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M)
M.jitteriness = max(M.jitteriness-5,0)
if(prob(80))
M.adjustBrainLoss(2*REM)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
if(prob(50))
M.drowsyness = max(M.drowsyness, 3)
if(prob(10))
@@ -1222,7 +1222,7 @@
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
color = "#9E6B38" // rgb: 158, 107, 56
taste_description = "metal"
pH = 13
pH = 11
/datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
name = "Foaming agent"
@@ -1231,7 +1231,7 @@
reagent_state = SOLID
color = "#664B63" // rgb: 102, 75, 99
taste_description = "metal"
pH = 12.5
pH = 11.5
/datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls.
name = "Smart foaming agent"
@@ -1519,20 +1519,6 @@
taste_description = "metal"
pH = 4.5
/datum/reagent/carpet
name = "Carpet"
id = "carpet"
description = "For those that need a more creative way to roll out a red carpet."
reagent_state = LIQUID
color = "#b51d05"
taste_description = "carpet" // Your tounge feels furry.
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet)
..()
/datum/reagent/bromine
name = "Bromine"
id = "bromine"
@@ -1686,6 +1672,143 @@
qdel(O)
new /obj/item/clothing/shoes/galoshes/dry(t_loc)
// Liquid Carpets
/datum/reagent/carpet
name = "Liquid Carpet"
id = "carpet"
description = "For those that need a more creative way to roll out a carpet."
reagent_state = LIQUID
color = "#b51d05"
taste_description = "carpet" // Your tounge feels furry.
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet)
..()
/datum/reagent/carpet/black
name = "Liquid Black Carpet"
id = "blackcarpet"
color = "#363636"
/datum/reagent/carpet/black/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/black)
..()
/datum/reagent/carpet/blackred
name = "Liquid Red Black Carpet"
id = "blackredcarpet"
color = "#342125"
/datum/reagent/carpet/blackred/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/blackred)
..()
/datum/reagent/carpet/monochrome
name = "Liquid Monochrome Carpet"
id = "monochromecarpet"
color = "#b4b4b4"
/datum/reagent/carpet/monochrome/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/monochrome)
..()
/datum/reagent/carpet/blue
name = "Liquid Blue Carpet"
id = "bluecarpet"
color = "#1256ff"
/datum/reagent/carpet/blue/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/blue)
..()
/datum/reagent/carpet/cyan
name = "Liquid Cyan Carpet"
id = "cyancarpet"
color = "#3acfb9"
/datum/reagent/carpet/cyan/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/cyan)
..()
/datum/reagent/carpet/green
name = "Liquid Green Carpet"
id = "greencarpet"
color = "#619b62"
/datum/reagent/carpet/green/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/green)
..()
/datum/reagent/carpet/orange
name = "Liquid Orange Carpet"
id = "orangecarpet"
color = "#cc7900"
/datum/reagent/carpet/orange/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/orange)
..()
/datum/reagent/carpet/purple
name = "Liquid Purple Carpet"
id = "purplecarpet"
color = "#6d3392"
/datum/reagent/carpet/purple/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/purple)
..()
/datum/reagent/carpet/red
name = "Liquid Red Carpet"
id = "redcarpet"
color = "#871515"
/datum/reagent/carpet/red/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/red)
..()
/datum/reagent/carpet/royalblack
name = "Liquid Royal Black Carpet"
id = "royalblackcarpet"
color = "#483d05"
/datum/reagent/carpet/royalblack/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/royalblack)
..()
/datum/reagent/carpet/royalblue
name = "Liquid Royal Blue Carpet"
id = "royalbluecarpet"
color = "#24227e"
/datum/reagent/carpet/royalblue/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/royalblue)
..()
// Virology virus food chems.
/datum/reagent/toxin/mutagen/mutagenvirusfood
@@ -1992,7 +2115,7 @@
can_synth = FALSE
var/datum/dna/original_dna
var/reagent_ticks = 0
invisible = TRUE
chemical_flags = REAGENT_INVISIBLE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
if(C && C.dna && data["desired_dna"])
@@ -471,7 +471,7 @@
toxpwr = 0
/datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/M)
M.adjustBrainLoss(3*REM, 150)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM, 150)
if(M.toxloss <= 60)
M.adjustToxLoss(1*REM, 0)
if(current_cycle >= 18)
@@ -950,3 +950,20 @@
to_chat(M, "<span class='warning'>Your missing arm aches from wherever you left it.</span>")
M.emote("sigh")
return ..()
/datum/reagent/toxin/brainhurtingjuice //oof ouch
name = "Brain Hurting Juice"
id = "brainhurtingjuice"
color = "#AAAAAA77" //RGBA: 170, 170, 170, 77
toxpwr = 0
taste_description = "brain hurting"
metabolization_rate = 5
/datum/reagent/toxin/brainhurtingjuice/on_mob_life(mob/living/carbon/M)
if(prob(50))
M.gain_trauma_type(BRAIN_TRAUMA_MILD)
else if(prob(50))
M.gain_trauma_type(BRAIN_TRAUMA_SEVERE)
else
M.gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
..()
@@ -32,6 +32,7 @@
var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect
var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics
var/FermiExplode = FALSE // If the chemical explodes in a special way
var/clear_conversion //bitflags for clear conversions; REACTION_CLEAR_IMPURE or REACTION_CLEAR_INVERSE
var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this.
@@ -68,6 +68,42 @@
results = list("synthflesh" = 3)
required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1)
/datum/chemical_reaction/synthtissue
name = "Synthtissue"
id = "synthtissue"
results = list("synthtissue" = 0.05)
required_reagents = list("synthflesh" = 0.01)
required_catalysts = list("nutriment" = 0.1)
//FermiChem vars:
OptimalTempMin = 305 // Lower area of bell curve for determining heat based rate reactions
OptimalTempMax = 315 // Upper end for above
ExplodeTemp = 1050 // Temperature at which reaction explodes
OptimalpHMin = 8.5 // 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 = 1 // How sharp the temperature exponential curve is (to the power of value)
CurveSharppH = 2.5 // How sharp the pH exponential curve is (to the power of value)
ThermicConstant = 0.01 // Temperature change per 1u produced
HIonRelease = 0.015 // pH change per 1u reaction (inverse for some reason)
RateUpLim = 0.05 // Optimal/max rate possible if all conditions are perfect
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
PurityMin = 0
/datum/chemical_reaction/synthtissue/FermiCreate(datum/reagents/holder, added_volume, added_purity)
var/datum/reagent/synthtissue/St = holder.has_reagent("synthtissue")
var/datum/reagent/N = holder.has_reagent("nutriment")
if(!St)
return
if(holder.chem_temp > 320)
var/temp_ratio = 1-(330 - holder.chem_temp)/10
holder.remove_reagent(src.id, added_volume*temp_ratio)
if(St.purity < 1)
St.volume *= St.purity
St.purity = 1
N.volume -= 0.002
St.data["grown_volume"] = St.data["grown_volume"] + added_volume
/datum/chemical_reaction/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
@@ -494,12 +494,6 @@
results = list("acetone" = 3)
required_reagents = list("oil" = 1, "welding_fuel" = 1, "oxygen" = 1)
/datum/chemical_reaction/carpet
name = "carpet"
id = "carpet"
results = list("carpet" = 2)
required_reagents = list("space_drugs" = 1, "blood" = 1)
/datum/chemical_reaction/oil
name = "Oil"
id = "oil"
@@ -641,3 +635,77 @@
results = list("shadowmutationtoxin" = 1)
required_reagents = list("liquid_dark_matter" = 5, "synaptizine" = 10, "oculine" = 10, "stablemutationtoxin" = 1)
required_temp = 600
// Liquid Carpets
/datum/chemical_reaction/carpet
name = "carpet"
id = "carpet"
results = list("carpet" = 2)
required_reagents = list("space_drugs" = 1, "blood" = 1)
/datum/chemical_reaction/carpet/black
name = "liquid black carpet"
id = "blackcarpet"
results = list("blackcarpet" = 2)
required_reagents = list("carpet" = 1, "carbon" = 1)
/datum/chemical_reaction/carpet/blackred
name = "liquid red black carpet"
id = "blackredcarpet"
results = list("blackredcarpet" = 2)
required_reagents = list("carpet" = 1, "charcoal" = 1)
/datum/chemical_reaction/carpet/monochrome
name = "liquid monochrome carpet"
id = "monochromecarpet"
results = list("monochromecarpet" = 2)
required_reagents = list("carpet" = 1, "oil" = 1)
/datum/chemical_reaction/carpet/blue
name = "liquid blue carpet"
id = "bluecarpet"
results = list("bluecarpet" = 2)
required_reagents = list("carpet" = 1, "tonic" = 1)
/datum/chemical_reaction/carpet/cyan
name = "liquid cyan carpet"
id = "cyancarpet"
results = list("cyancarpet" = 2)
required_reagents = list("carpet" = 1, "ice" = 1)
/datum/chemical_reaction/carpet/green
name = "liquid green carpet"
id = "greencarpet"
results = list("greencarpet" = 2)
required_reagents = list("carpet" = 1, "sacid" = 1)
/datum/chemical_reaction/carpet/orange
name = "liquid orange carpet"
id = "orangecarpet"
results = list("orangecarpet" = 2)
required_reagents = list("carpet" = 1, "orangejuice" = 1)
/datum/chemical_reaction/carpet/purple
name = "liquid purple carpet"
id = "purplecarpet"
results = list("purplecarpet" = 2)
required_reagents = list("carpet" = 1, "stable_plasma" = 1)
/datum/chemical_reaction/carpet/red
name = "liquid red carpet"
id = "redcarpet"
results = list("redcarpet" = 2)
required_reagents = list("carpet" = 1, "welding_fuel" = 1)
/datum/chemical_reaction/carpet/royalblack
name = "liquid royal black carpet"
id = "royalblackcarpet"
results = list("royalblackcarpet" = 2)
required_reagents = list("carpet" = 1, "blackpepper" = 1)
/datum/chemical_reaction/carpet/royalblue
name = "liquid royal blue carpet"
id = "royalbluecarpet"
results = list("royalbluecarpet" = 2)
required_reagents = list("carpet" = 1, "clonexadone" = 1)