what is this

This commit is contained in:
Fermi
2019-09-03 20:30:21 +01:00
parent 60bd6bf387
commit 7890ad08d5
1140 changed files with 4619 additions and 1884 deletions
+12 -14
View File
@@ -1,3 +1,5 @@
#define CHEMICAL_QUANTISATION_LEVEL 0.0001
/proc/build_chemical_reagent_list()
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
@@ -94,7 +96,7 @@
var/list/data = list()
for(var/r in reagent_list) //no reagents will be left behind
var/datum/reagent/R = r
data += "[R.id] ([round(R.volume, 0.1)]u)"
data += "[R.id] ([round(R.volume, CHEMICAL_QUANTISATION_LEVEL)]u)"
//Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
return english_list(data)
@@ -471,7 +473,7 @@
return 0
for(var/B in cached_required_reagents)
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.01))
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL))
for(var/P in selected_reaction.results)
targetVol = cached_results[P]*multiplier
@@ -498,7 +500,7 @@
return 0
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.01))
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL))
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE)
@@ -646,8 +648,8 @@
addChemAmmount = deltaT * stepChemAmmount
if (addChemAmmount >= (targetVol - reactedVol))
addChemAmmount = (targetVol - reactedVol)
if (addChemAmmount < 0.01)
addChemAmmount = 0.01
if (addChemAmmount < CHEMICAL_QUANTISATION_LEVEL)
addChemAmmount = CHEMICAL_QUANTISATION_LEVEL
removeChemAmmount = (addChemAmmount/cached_results[P])
//This is kept for future bugtesters.
//message_admins("Reaction vars: PreReacted: [reactedVol] of [targetVol]. deltaT [deltaT], multiplier [multiplier], Step [stepChemAmmount], uncapped Step [deltaT*(multiplier*cached_results[P])], addChemAmmount [addChemAmmount], removeFactor [removeChemAmmount] Pfactor [cached_results[P]], adding [addChemAmmount]")
@@ -692,11 +694,7 @@
return
//Make sure things are limited.
if (pH > 14)
pH = 14
else if (pH < 0)
pH = 0
//some beakers melt at extremes. This proc is called in add_reagent
pH = CLAMP(pH, 0, 14)
//return said amount to compare for next step.
return (reactedVol)
@@ -743,7 +741,7 @@
total_volume = 0
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume < 0.1)
if(R.volume < CHEMICAL_QUANTISATION_LEVEL)
del_reagent(R.id)
else
total_volume += R.volume
@@ -812,7 +810,7 @@
if(!isnum(amount) || !amount)
return FALSE
if(amount <= 0.00)
if(amount <= CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems.
return FALSE
var/datum/reagent/D = GLOB.chemical_reagents_list[reagent]
@@ -971,7 +969,7 @@
if(!amount)
return R
else
if(R.volume >= amount)
if(round(R.volume, CHEMICAL_QUANTISATION_LEVEL) >= amount)
return R
else
return 0
@@ -983,7 +981,7 @@
for(var/_reagent in cached_reagents)
var/datum/reagent/R = _reagent
if (R.id == reagent)
return R.volume
return round(R.volume, CHEMICAL_QUANTISATION_LEVEL)
return 0
@@ -139,12 +139,14 @@
/obj/machinery/chem_dispenser/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
to_chat(user, "<span class='warning'>[src] has no functional safeties to emag.</span>")
return
to_chat(user, "<span class='notice'>You short out [src]'s safeties.</span>")
dispensable_reagents |= emagged_reagents//add the emagged reagents to the dispensable ones
obj_flags |= EMAGGED
return TRUE
/obj/machinery/chem_dispenser/ex_act(severity, target)
if(severity < 3)
@@ -21,6 +21,7 @@
var/analyzeVars[0]
var/useramount = 30 // Last used amount
var/list/pillStyles
var/fermianalyze //Give more detail on fermireactions on analysis
/obj/machinery/chem_master/Initialize()
create_reagents(100)
@@ -102,12 +103,9 @@
updateUsrDialog()
update_icon()
else if(!condi && istype(I, /obj/item/storage/pill_bottle))
if(bottle)
to_chat(user, "<span class='warning'>A pill bottle is already loaded into [src]!</span>")
return
if(!user.transferItemToLoc(I, src))
return
bottle = I
replace_pillbottle(user, I)
to_chat(user, "<span class='notice'>You add [I] into the dispenser slot.</span>")
updateUsrDialog()
else
@@ -131,12 +129,23 @@
update_icon()
return TRUE
/obj/machinery/chem_master/on_deconstruction()
replace_beaker(usr)
/obj/machinery/chem_master/proc/replace_pillbottle(mob/living/user, obj/item/storage/pill_bottle/new_bottle)
if(bottle)
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
else
adjust_item_drop_location(bottle)
if(new_bottle)
bottle = new_bottle
else
bottle = null
update_icon()
return TRUE
/obj/machinery/chem_master/on_deconstruction()
replace_beaker(usr)
replace_pillbottle(usr)
return ..()
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
@@ -162,6 +171,7 @@
data["condi"] = condi
data["screen"] = screen
data["analyzeVars"] = analyzeVars
data["fermianalyze"] = fermianalyze
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
@@ -195,11 +205,8 @@
. = TRUE
if("ejectp")
if(bottle)
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
bottle = null
. = TRUE
replace_pillbottle(usr)
. = TRUE
if("transferToBuffer")
if(beaker)
@@ -247,14 +254,14 @@
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/pill/P
var/target_loc = drop_location()
var/target_loc = bottle ? bottle : drop_location()
var/drop_threshold = INFINITY
if(bottle)
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
for(var/i = 0; i < amount; i++)
for(var/i in 1 to amount)
if(i < drop_threshold)
P = new(target_loc)
else
@@ -350,10 +357,10 @@
return
var/amount_full = 0
var/vol_part = min(reagents.total_volume, 30)
var/vol_part = min(reagents.total_volume, 60)
if(text2num(many))
amount_full = round(reagents.total_volume / 30)
vol_part = reagents.total_volume % 30
amount_full = round(reagents.total_volume / 60)
vol_part = reagents.total_volume % 60
var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -363,7 +370,7 @@
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
P.name = trim("[name] hypovial")
adjust_item_drop_location(P)
reagents.trans_to(P, 30)
reagents.trans_to(P, 60)
if(vol_part)
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
@@ -384,7 +391,14 @@
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
if(istype(R, /datum/reagent/fermi))
fermianalyze = TRUE
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id)
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = initial(R.purity), "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return
@@ -437,4 +451,4 @@
condi = TRUE
#undef PILL_STYLE_COUNT
#undef RANDOM_PILL_STYLE
#undef RANDOM_PILL_STYLE
@@ -44,6 +44,7 @@
var/DoNotSplit = FALSE // If impurity is handled within the main chem itself
var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging.
var/metabolizing = FALSE
var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
@@ -230,7 +230,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of vodka"
glass_desc = "The glass contain wodka. Xynta."
shot_glass_icon_state = "shotglassclear"
pH = 4
pH = 8.1
/datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M)
M.radiation = max(M.radiation-2,0)
@@ -528,6 +528,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Vodka martini"
glass_desc ="A bastardisation of the classic martini. Still great."
/datum/reagent/consumable/ethanol/white_russian
name = "White Russian"
id = "whiterussian"
@@ -2102,7 +2103,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M)
if(M.drunkenness > 40)
if(stored_teleports)
do_teleport(M, get_turf(M), rand(1,3))
do_teleport(M, get_turf(M), rand(1,3), channel = TELEPORT_CHANNEL_WORMHOLE)
stored_teleports--
if(prob(10))
stored_teleports += rand(2,6)
@@ -323,7 +323,7 @@
victim.blind_eyes(2)
victim.confused = max(M.confused, 3)
victim.damageoverlaytemp = 60
victim.Knockdown(60, override_stamdmg = min(reac_volume * 3, 15))
victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 3, 15))
return
else if ( eyes_covered ) // Eye cover is better than mouth cover
victim.blur_eyes(3)
@@ -336,7 +336,7 @@
victim.blind_eyes(3)
victim.confused = max(M.confused, 6)
victim.damageoverlaytemp = 75
victim.Knockdown(100, override_stamdmg = min(reac_volume * 5, 25))
victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 5, 25))
victim.update_damage_hud()
/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M)
@@ -351,7 +351,7 @@
//We only get 30u to start with...
/datum/reagent/fuel/holyoil/reaction_obj(obj/O, reac_volume)
. = ..()
. = ..()
if(istype(O, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = O
reac_volume = min(reac_volume, M.amount)
@@ -1013,7 +1013,7 @@
/datum/reagent/bluespace/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg') //4 tiles per crystal
do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
..()
/datum/reagent/bluespace/on_mob_life(mob/living/carbon/M)
@@ -1025,7 +1025,7 @@
..()
/mob/living/proc/bluespace_shuffle()
do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg')
do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
/datum/reagent/aluminium
name = "Aluminium"
@@ -1993,3 +1993,41 @@
P.length += added_length
P.update()
..()
/datum/reagent/changeling_string
name = "UNKNOWN"
id = "changeling_sting_real"
description = "404: Chemical not found."
metabolization_rate = REAGENTS_METABOLISM
color = "#0000FF"
can_synth = FALSE
var/datum/dna/original_dna
var/reagent_ticks = 0
invisible = TRUE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
if(C && C.dna && data["desired_dna"])
original_dna = new C.dna.type
C.dna.copy_dna(original_dna)
var/datum/dna/new_dna = data["desired_dna"]
new_dna.copy_dna(C.dna)
C.real_name = new_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C)
if(original_dna)
original_dna.copy_dna(C.dna)
C.real_name = original_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/Destroy()
qdel(original_dna)
return ..()
@@ -54,7 +54,7 @@
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
. = ..()
if((!proximity) || !spillable || !check_allowed_items(target,target_self=1))
if((!proximity) || !check_allowed_items(target,target_self=1))
return
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
@@ -0,0 +1,177 @@
/obj/item/reagent_containers/rag
name = "damp rag"
desc = "For cleaning up messes, you suppose."
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/toy.dmi'
icon_state = "rag"
item_flags = NOBLUDGEON
reagent_flags = OPENCONTAINER
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 5
spillable = FALSE
var/wipe_sound
var/soak_efficiency = 1
var/extinguish_efficiency = 0
var/action_speed = 3 SECONDS
var/damp_threshold = 0.5
/obj/item/reagent_containers/rag/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/reagent_containers/rag/examine(mob/user)
. = ..()
if(reagents.total_volume)
to_chat(user, "<span class='notice'>Alt-Click to squeeze the liquids out of it.</span>")
/obj/item/reagent_containers/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity)
. = ..()
if(!proximity)
return
if(iscarbon(A) && A.reagents && reagents.total_volume)
var/mob/living/carbon/C = A
var/reagentlist = pretty_string_from_reagent_list(reagents)
var/log_object = "a damp rag containing [reagentlist]"
if(user.a_intent == INTENT_HARM && !C.is_mouth_covered())
reagents.reaction(C, INGEST)
reagents.trans_to(C, 5)
C.visible_message("<span class='danger'>[user] has smothered \the [C] with \the [src]!</span>", "<span class='userdanger'>[user] has smothered you with \the [src]!</span>", "<span class='italics'>You hear some struggling and muffled cries of surprise.</span>")
log_combat(user, C, "smothered", log_object)
else
reagents.reaction(C, TOUCH)
reagents.remove_all(5)
C.visible_message("<span class='notice'>[user] has touched \the [C] with \the [src].</span>")
log_combat(user, C, "touched", log_object)
else if(istype(A) && src in user)
user.visible_message("[user] starts to wipe down [A] with [src]!", "<span class='notice'>You start to wipe down [A] with [src]...</span>")
if(do_after(user, action_speed, target = A))
user.visible_message("[user] finishes wiping off [A]!", "<span class='notice'>You finish wiping off [A].</span>")
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
return
/obj/item/reagent_containers/rag/pre_altattackby(mob/living/M, mob/living/user, params)
if(istype(M) && user.a_intent == INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
if(M.on_fire)
user.visible_message("<span class='warning'>\The [user] uses \the [src] to pat out [M == user ? "[user.p_their()]" : "\the [M]'s"] flames!</span>")
if(hitsound)
playsound(M, hitsound, 25, 1)
M.adjust_fire_stacks(-min(extinguish_efficiency, M.fire_stacks))
else
if(reagents.total_volume > (volume * damp_threshold))
to_chat(user, "<span class='warning'>\The [src] is too drenched to be used to dry [user == M ? "yourself" : "\the [M]"] off.</span>")
return TRUE
user.visible_message("<span class='notice'>\The [user] starts drying [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src]...</span>")
if(do_mob(user, M, action_speed))
if(reagents.total_volume > (volume * damp_threshold))
return
user.visible_message("<span class='notice'>\The [user] dries [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src].</span>")
if(wipe_sound)
playsound(M, wipe_sound, 25, 1)
if(M.fire_stacks)
var/minus_plus = M.fire_stacks < 0 ? 1 : -1
var/amount = min(abs(M.fire_stacks), soak_efficiency)
var/r_id = "fuel"
if(M.fire_stacks < 0)
r_id = "water"
reagents.add_reagent(r_id, amount * 0.3)
M.adjust_fire_stacks(minus_plus * amount)
M.wash_cream()
return TRUE
return ..()
/obj/item/reagent_containers/rag/AltClick(mob/user)
. = ..()
if(reagents.total_volume && user.canUseTopic(src, BE_CLOSE))
to_chat(user, "<span class='notice'>You start squeezing the liquids out of \the [src]...</span>")
if(do_after(user, action_speed, TRUE, src))
to_chat(user, "<span class='notice'>You squeeze \the [src] dry.</span>")
var/atom/react_loc = get_turf(src)
if(ismob(react_loc))
react_loc = react_loc.loc
if(react_loc)
reagents.reaction(react_loc, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/rag/towel
name = "towel"
desc = "A soft cotton towel."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "towel"
item_state = "towel"
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING
item_flags = NOBLUDGEON | NO_UNIFORM_REQUIRED //so it can be worn on the belt slot even with no uniform.
force = 1
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("whipped")
hitsound = 'sound/items/towelwhip.ogg'
volume = 10
total_mass = 2
wipe_sound = 'sound/items/towelwipe.ogg'
soak_efficiency = 4
extinguish_efficiency = 3
var/flat_icon = "towel_flat"
var/folded_icon = "towel"
var/list/possible_colors
/obj/item/reagent_containers/rag/towel/Initialize()
. = ..()
if(possible_colors)
add_atom_colour(pick(possible_colors), FIXED_COLOUR_PRIORITY)
/obj/item/reagent_containers/rag/towel/attack(mob/living/M, mob/living/user)
if(user.a_intent == INTENT_HARM)
DISABLE_BITFIELD(item_flags, NOBLUDGEON)
. = TRUE
..()
if(.)
ENABLE_BITFIELD(item_flags, NOBLUDGEON)
/obj/item/reagent_containers/rag/towel/equipped(mob/living/user, slot)
. = ..()
switch(slot)
if(SLOT_BELT)
body_parts_covered = GROIN|LEGS
if(SLOT_WEAR_SUIT)
body_parts_covered = CHEST|GROIN|LEGS
if(SLOT_HEAD)
body_parts_covered = HEAD
flags_inv = HIDEHAIR
/obj/item/reagent_containers/rag/towel/dropped(mob/user)
. = ..()
body_parts_covered = NONE
flags_inv = NONE
/obj/item/reagent_containers/rag/towel/attack_self(mob/user)
if(!user.CanReach(src) || !user.dropItemToGround(src))
return
to_chat(user, "<span class='notice'>You lay out \the [src] flat on the ground.</span>")
icon_state = flat_icon
layer = BELOW_OBJ_LAYER
/obj/item/reagent_containers/rag/towel/pickup(mob/living/user)
. = ..()
icon_state = folded_icon
layer = initial(layer)
/obj/item/reagent_containers/rag/towel/on_reagent_change(changetype)
force = initial(force) + round(reagents.total_volume * 0.5)
/obj/item/reagent_containers/rag/towel/random
possible_colors = list("#FF0000","#FF7F00","#FFFF00","#00FF00","#0000FF","#4B0082","#8F00FF")
/obj/item/reagent_containers/rag/towel/syndicate
name = "syndicate towel"
desc = "Truly a weapon of mass destruction."
possible_colors = list("#DD1A1A", "#DB4325", "#E02700")
force = 4
armour_penetration = 10
volume = 20
soak_efficiency = 6
extinguish_efficiency = 5
action_speed = 15
damp_threshold = 0.8
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet.