Merge pull request #5688 from VOREStation/upstream-merge-6396

[MIRROR] Chemistry Expansion
This commit is contained in:
Novacat
2019-08-21 18:01:11 -04:00
committed by GitHub
20 changed files with 802 additions and 5 deletions

View File

@@ -335,3 +335,17 @@
cost = 30
containertype = /obj/structure/closet/crate/medical
containername = "Defibrillator crate"
/datum/supply_pack/med/distillery
name = "Chemical distiller crate"
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
cost = 175
containertype = /obj/structure/largecrate
containername = "Chemical distiller crate"
/datum/supply_pack/med/advdistillery
name = "Industrial Chemical distiller crate"
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
cost = 250
containertype = /obj/structure/largecrate
containername = "Industrial Chemical distiller crate"

View File

@@ -149,6 +149,8 @@
var/power_losses
var/last_power_draw = 0
var/obj/item/weapon/cell/cell
var/use_cell = TRUE
var/removeable_cell = TRUE
/obj/machinery/portable_atmospherics/powered/powered()
if(use_power) //using area power
@@ -158,7 +160,7 @@
return 0
/obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/cell))
if(use_cell && istype(I, /obj/item/weapon/cell))
if(cell)
to_chat(user, "There is already a power cell installed.")
return
@@ -173,7 +175,7 @@
power_change()
return
if(I.is_screwdriver())
if(I.is_screwdriver() && removeable_cell)
if(!cell)
to_chat(user, "<span class='warning'>There is no power cell installed.</span>")
return

View File

@@ -102,6 +102,12 @@
circuit = /obj/item/weapon/circuitboard/grinder
frame_size = 3
/datum/frame/frame_types/reagent_distillery
name = "Distillery"
frame_class = FRAME_CLASS_MACHINE
circuit = /obj/item/weapon/circuitboard/distiller
frame_size = 4
/datum/frame/frame_types/display
name = "Display"
frame_class = FRAME_CLASS_DISPLAY

View File

@@ -170,6 +170,15 @@
/obj/item/weapon/stock_parts/gear = 1,
/obj/item/weapon/reagent_containers/glass/beaker/large = 1)
/obj/item/weapon/circuitboard/distiller
build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
board_type = new /datum/frame/frame_types/reagent_distillery
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/motor = 2,
/obj/item/weapon/stock_parts/gear = 1)
/obj/item/weapon/circuitboard/teleporter_hub
name = T_BOARD("teleporter hub")
build_path = /obj/machinery/teleport/hub

View File

@@ -0,0 +1,17 @@
/*
* Modifiers caused by chemicals or organs specifically.
*/
/datum/modifier/cryogelled
name = "cryogelled"
desc = "Your body begins to freeze."
mob_overlay_state = "chilled"
on_created_text = "<span class='danger'>You feel like you're going to freeze! It's hard to move.</span>"
on_expired_text = "<span class='warning'>You feel somewhat warmer and more mobile now.</span>"
stacks = MODIFIER_STACK_ALLOWED
slowdown = 0.1
evasion = -5
attack_speed_percent = 1.1
disable_duration_percent = 1.05

View File

@@ -281,6 +281,28 @@
var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc)
reagents.trans_to_obj(P,50)
else if (href_list["createpatch"])
if(reagents.total_volume < 1) //Sanity checking.
return
var/name = sanitizeSafe(input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([round(reagents.total_volume)]u)") as null|text, MAX_NAME_LEN)
if(!name) //Blank name (sanitized to nothing, or left empty) or cancel
return
if(reagents.total_volume < 1) //Sanity checking.
return
var/obj/item/weapon/reagent_containers/pill/patch/P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc)
if(!name) name = reagents.get_master_reagent_name()
P.name = "[name] patch"
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
reagents.trans_to_obj(P, 60)
if(src.loaded_pill_bottle)
if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space)
P.loc = loaded_pill_bottle
else if(href_list["pill_sprite"])
pillsprite = href_list["pill_sprite"]
else if(href_list["bottle_sprite"])

View File

@@ -16,6 +16,28 @@
M.add_chemical_effect(CE_STABLE, 15)
M.add_chemical_effect(CE_PAINKILLER, 10)
/datum/reagent/inaprovaline/topical
name = "Inaprovalaze"
id = "inaprovalaze"
description = "Inaprovalaze is a topical variant of Inaprovaline."
taste_description = "bitterness"
reagent_state = LIQUID
color = "#00BFFF"
overdose = REAGENTS_OVERDOSE * 2
metabolism = REM * 0.5
scannable = 1
touch_met = REM * 0.75
/datum/reagent/inaprovaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
..()
M.adjustToxLoss(2 * removed)
/datum/reagent/inaprovaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.add_chemical_effect(CE_STABLE, 20)
M.add_chemical_effect(CE_PAINKILLER, 12)
/datum/reagent/bicaridine
name = "Bicaridine"
id = "bicaridine"
@@ -51,6 +73,33 @@
if(W.damage <= 0)
O.wounds -= W
/datum/reagent/bicaridine/topical
name = "Bicaridaze"
id = "bicaridaze"
description = "Bicaridaze is a topical variant of the chemical Bicaridine."
taste_description = "bitterness"
taste_mult = 3
reagent_state = LIQUID
color = "#BF0000"
overdose = REAGENTS_OVERDOSE * 0.75
scannable = 1
touch_met = REM * 0.75
/datum/reagent/bicaridine/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
var/chem_effective = 1
if(alien == IS_SLIME)
chem_effective = 0.75
if(alien != IS_DIONA)
..(M, alien, removed * chem_effective)
M.adjustToxLoss(2 * removed)
/datum/reagent/bicaridine/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
var/chem_effective = 1
if(alien == IS_SLIME)
chem_effective = 0.75
if(alien != IS_DIONA)
M.heal_organ_damage(6 * removed * chem_effective, 0)
/datum/reagent/kelotane
name = "Kelotane"
id = "kelotane"
@@ -87,6 +136,33 @@
if(alien != IS_DIONA)
M.heal_organ_damage(0, 8 * removed * chem_effective) //VOREStation edit
/datum/reagent/dermaline/topical
name = "Dermalaze"
id = "dermalaze"
description = "Dermalaze is a topical variant of the chemical Dermaline."
taste_description = "bitterness"
taste_mult = 1.5
reagent_state = LIQUID
color = "#FF8000"
overdose = REAGENTS_OVERDOSE * 0.4
scannable = 1
touch_met = REM * 0.75
/datum/reagent/dermaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
var/chem_effective = 1
if(alien == IS_SLIME)
chem_effective = 0.75
if(alien != IS_DIONA)
..(M, alien, removed * chem_effective)
M.adjustToxLoss(2 * removed)
/datum/reagent/dermaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
var/chem_effective = 1
if(alien == IS_SLIME)
chem_effective = 0.75
if(alien != IS_DIONA)
M.heal_organ_damage(0, 12 * removed * chem_effective)
/datum/reagent/dylovene
name = "Dylovene"
id = "anti_toxin"
@@ -203,6 +279,10 @@
M.heal_organ_damage(1.5 * removed, 1.5 * removed * chem_effective)
M.adjustToxLoss(-1.5 * removed * chem_effective)
/datum/reagent/tricordrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
affect_blood(M, alien, removed * 0.4)
/datum/reagent/cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
@@ -865,6 +945,9 @@
to_chat(M, "<span class='warning'>Your senses feel unfocused, and divided.</span>")
M.add_chemical_effect(CE_ANTIBIOTIC, dose >= overdose ? ANTIBIO_OD : ANTIBIO_NORM)
/datum/reagent/spaceacillin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.8) // Not 100% as effective as injections, though still useful.
/datum/reagent/corophizine
name = "Corophizine"
id = "corophizine"

View File

@@ -0,0 +1,58 @@
/*
* Modifier-applying chemicals.
*/
/datum/reagent/modapplying
name = "brute juice"
id = "berserkmed"
description = "A liquid that is capable of causing a prolonged state of heightened aggression and durability."
taste_description = "metal"
reagent_state = LIQUID
color = "#ff5555"
metabolism = REM
var/modifier_to_add = /datum/modifier/berserk
var/modifier_duration = 2 SECONDS // How long, per unit dose, will this last?
/datum/reagent/modapplying/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.add_modifier(modifier_to_add, dose * modifier_duration)
/datum/reagent/modapplying/cryofluid
name = "cryogenic slurry"
id = "cryoslurry"
description = "An incredibly strange liquid that rapidly absorbs thermal energy from materials it contacts."
taste_description = "siberian hellscape"
color = "#4CDBDB"
metabolism = REM * 0.5
modifier_to_add = /datum/modifier/cryogelled
modifier_duration = 3 SECONDS
/datum/reagent/modapplying/cryofluid/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..(M, alien, removed)
M.bodytemperature -= removed * 20
/datum/reagent/modapplying/cryofluid/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 2.5)
/datum/reagent/modapplying/cryofluid/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.6)
/datum/reagent/modapplying/cryofluid/touch_mob(var/mob/M, var/amount)
if(isliving(M))
var/mob/living/L = M
for(var/I = 1 to rand(1, round(amount + 1)))
L.add_modifier(modifier_to_add, amount * rand(modifier_duration / 2, modifier_duration * 2))
return
/datum/reagent/modapplying/cryofluid/touch_turf(var/turf/T, var/amount)
if(istype(T, /turf/simulated/floor/water) && prob(amount))
T.visible_message("<span class='danger'>\The [T] crackles loudly as the cryogenic fluid causes it to boil away, leaving behind a hard layer of ice.</span>")
T.ChangeTurf(/turf/simulated/floor/outdoors/ice, 1, 1, TRUE)
else
if(istype(T, /turf/simulated))
var/turf/simulated/S = T
S.freeze_floor()
return

View File

@@ -11,6 +11,7 @@
metabolism = REM * 0.25 // 0.05 by default. Hopefully enough to get some help, or die horribly, whatever floats your boat
filtered_organs = list(O_LIVER, O_KIDNEYS)
var/strength = 4 // How much damage it deals per unit
var/skin_danger = 0.2 // The multiplier for how effective the toxin is when making skin contact.
/datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(strength && alien != IS_DIONA)
@@ -23,6 +24,9 @@
M.heal_organ_damage((10/strength) * removed, (10/strength) * removed) //Doses of toxins below 10 units, and 10 strength, are capable of providing useful compounds for repair.
M.adjustToxLoss(strength * removed)
/datum/reagent/toxin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.2)
/datum/reagent/toxin/plasticide
name = "Plasticide"
id = "plasticide"
@@ -58,6 +62,7 @@
reagent_state = LIQUID
color = "#005555"
strength = 8
skin_danger = 0.4
/datum/reagent/toxin/neurotoxic_protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
@@ -121,6 +126,7 @@
color = "#9D14DB"
strength = 30
touch_met = 5
skin_danger = 1
/datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount)
if(istype(L))

View File

@@ -34,6 +34,7 @@
var/reaction_sound = 'sound/effects/bubbles.ogg'
var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
/datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder)
//check that all the required reagents are present
if(!holder.has_all_reagents(required_reagents))

View File

@@ -0,0 +1,170 @@
/datum/chemical_reaction/distilling
// name = null
// id = null
// result = null
// required_reagents = list()
// catalysts = list()
// inhibitors = list()
// result_amount = 0
//how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros.
reaction_rate = HALF_LIFE(6)
//if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high.
//0.5 = 50% yield -> reaction will only proceed halfway until products are removed.
// yield = 1.0
//If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios),
//the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts.
// min_reaction = 2
mix_message = "The solution churns."
reaction_sound = 'sound/effects/slosh.ogg'
// log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
var/list/temp_range = list(T0C, T20C)
var/temp_shift = 0 // How much the temperature changes when the reaction occurs.
/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder)
//check that all the required reagents are present
if(!holder.has_all_reagents(required_reagents))
return 0
//check that all the required catalysts are present in the required amount
if(!holder.has_all_reagents(catalysts))
return 0
//check that none of the inhibitors are present in the required amount
if(holder.has_any_reagent(inhibitors))
return 0
if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
return 0
else // Super special temperature check.
var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2])
return 0
return 1
/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume)
if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
RD.current_temp += temp_shift
return
// Subtypes //
// Biomass
/datum/chemical_reaction/distilling/biomass
name = "Distilling Biomass"
id = "distill_biomass"
result = "biomass"
required_reagents = list("blood" = 1, "sugar" = 1, "phoron" = 0.5)
result_amount = 1 // 40 units per sheet, requires actually using the machine, and having blood to spare.
temp_range = list(T20C + 80, T20C + 130)
temp_shift = -2
// Medicinal
/datum/chemical_reaction/distilling/inaprovalaze
name = "Distilling Inaprovalaze"
id = "distill_inaprovalaze"
result = "inaprovalaze"
required_reagents = list("inaprovaline" = 2, "foaming_agent" = 1)
result_amount = 2
reaction_rate = HALF_LIFE(10)
temp_range = list(T0C + 100, T0C + 120)
/datum/chemical_reaction/distilling/bicaridaze
name = "Distilling Bicaridaze"
id = "distill_bicaridaze"
result = "bicaridaze"
required_reagents = list("bicaridine" = 2, "foaming_agent" = 1)
result_amount = 2
reaction_rate = HALF_LIFE(10)
temp_range = list(T0C + 110, T0C + 130)
/datum/chemical_reaction/distilling/dermalaze
name = "Distilling Dermalaze"
id = "distill_dermalaze"
result = "dermalaze"
required_reagents = list("dermaline" = 2, "foaming_agent" = 1)
result_amount = 2
reaction_rate = HALF_LIFE(10)
temp_range = list(T0C + 115, T0C + 130)
// Alcohol
/datum/chemical_reaction/distilling/beer
name = "Distilling Beer"
id = "distill_beer"
result = "beer"
required_reagents = list("nutriment" = 1, "water" = 1, "sugar" = 1)
result_amount = 2
reaction_rate = HALF_LIFE(30)
temp_range = list(T20C, T20C + 2)
/datum/chemical_reaction/distilling/ale
name = "Distilling Ale"
id = "distill_ale"
result = "ale"
required_reagents = list("nutriment" = 1, "beer" = 1)
inhibitors = list("water" = 1)
result_amount = 2
reaction_rate = HALF_LIFE(30)
temp_shift = 0.5
temp_range = list(T0C + 7, T0C + 13)
// Unique
/datum/chemical_reaction/distilling/berserkjuice
name = "Distilling Brute Juice"
id = "distill_brutejuice"
result = "berserkmed"
required_reagents = list("biomass" = 1, "hyperzine" = 3, "synaptizine" = 2, "phoron" = 1)
result_amount = 3
temp_range = list(T0C + 600, T0C + 700)
temp_shift = 4
/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume)
..()
if(prob(1))
var/turf/T = get_turf(holder.my_atom)
explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5))
return
/datum/chemical_reaction/distilling/cryogel
name = "Distilling Cryogellatin"
id = "distill_cryoslurry"
result = "cryoslurry"
required_reagents = list("frostoil" = 7, "enzyme" = 3, "plasticide" = 3, "foaming_agent" = 2)
inhibitors = list("water" = 5)
result_amount = 1
temp_range = list(0, 15)
temp_shift = 20
/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume)
..()
if(prob(1))
var/turf/T = get_turf(holder.my_atom)
var/datum/effect/effect/system/smoke_spread/frost/F = new (holder.my_atom)
F.set_up(6, 0, T)
F.start()
return

View File

@@ -0,0 +1,317 @@
/*
* Distillery, used for over-time temperature-based mixes.
*/
/obj/machinery/portable_atmospherics/powered/reagent_distillery
name = "chemical distillery"
desc = "A complex machine utilizing state-of-the-art components to mix chemicals at different temperatures."
use_power = 1
icon = 'icons/obj/machines/reagent.dmi'
icon_state = "distiller"
var/base_state // The string var used in update icon for overlays, either set manually or initialized.
power_rating = 3000
power_losses = 240
var/on = FALSE
var/target_temp = T20C
var/max_temp = T20C + 300
var/min_temp = T0C - 10
var/current_temp = T20C
var/use_atmos = FALSE // If true, this machine will be connectable to ports, and use gas mixtures as the source of heat, rather than its internal controls.
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use")
var/static/radial_pump = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pump")
var/static/radial_eject_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_input")
var/static/radial_eject_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_output")
var/static/radial_adjust_temp = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_temp")
var/static/radial_install_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add")
var/static/radial_install_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add")
var/static/radial_inspectgauges = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_lookat")
var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
// Overlay holders so we don't have to constantly remake them.
var/image/overlay_output_beaker
var/image/overlay_input_beaker
var/image/overlay_off
var/image/overlay_ready
var/image/overlay_cooling
var/image/overlay_heating
var/image/overlay_dumping
var/image/overlay_connected
// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back.
var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir
var/obj/item/weapon/reagent_containers/glass/InputBeaker
var/obj/item/weapon/reagent_containers/glass/OutputBeaker
// A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping.
var/efficiency = 1
/obj/item/weapon/reagent_containers/glass/distilling
name = "distilling chamber"
desc = "You should not be seeing this."
volume = 600
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master
/obj/item/weapon/reagent_containers/glass/distilling/Destroy()
Master = null
..()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize()
..()
Reservoir = new (src)
Reservoir.Master = src
if(!base_state)
base_state = icon_state
setup_overlay_vars()
update_icon()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/proc/setup_overlay_vars()
overlay_output_beaker = image(icon = src.icon, icon_state = "[base_state]-output")
overlay_input_beaker = image(icon = src.icon, icon_state = "[base_state]-input")
overlay_off = image(icon = src.icon, icon_state = "[base_state]-bad")
overlay_ready = image(icon = src.icon, icon_state = "[base_state]-good")
overlay_cooling = image(icon = src.icon, icon_state = "[base_state]-cool")
overlay_heating = image(icon = src.icon, icon_state = "[base_state]-heat")
overlay_dumping = image(icon = src.icon, icon_state = "[base_state]-dump")
overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector")
/obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy()
qdel(Reservoir)
Reservoir = null
if(InputBeaker)
qdel(InputBeaker)
InputBeaker = null
if(OutputBeaker)
qdel(OutputBeaker)
OutputBeaker = null
..()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/attack_hand(mob/user)
var/list/options = list()
options["examine"] = radial_examine
options["use"] = radial_use
options["inspect gauges"] = radial_inspectgauges
options["pulse agitator"] = radial_mix
if(InputBeaker)
options["eject input"] = radial_eject_input
if(OutputBeaker)
options["eject output"] = radial_eject_output
if(!use_atmos)
options["adjust temp"] = radial_adjust_temp
if(length(options) < 1)
return
var/list/choice = list()
if(length(options) == 1)
for(var/key in options)
choice = key
else
choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
switch(choice)
if("examine")
examine(user)
if("use")
if(powered())
on = !on
to_chat(user, "<span class='notice'>You turn \the [src] [on ? "on" : "off"].</span>")
if("inspect gauges")
to_chat(user, "<span class='notice'>\The [src]'s gauges read:</span>")
if(!use_atmos)
to_chat(user, "<span class='notice'>- Target Temperature:</span> <span class='warning'>[target_temp]</span>")
to_chat(user, "<span class='notice'>- Temperature:</span> <span class='warning'>[current_temp]</span>")
if("pulse agitator")
to_chat(user, "<span class='notice'>You press \the [src]'s chamber agitator button.</span>")
if(on)
visible_message("<span class='notice'>\The [src] rattles to life.</span>")
Reservoir.reagents.handle_reactions()
else
spawn(1 SECOND)
to_chat(user, "<span class='notice'>Nothing happens..</span>")
if("eject input")
if(InputBeaker)
InputBeaker.forceMove(get_turf(src))
InputBeaker = null
if("eject output")
if(OutputBeaker)
OutputBeaker.forceMove(get_turf(src))
OutputBeaker = null
if("adjust temp")
target_temp = input("Choose a target temperature.", "Temperature.", T20C) as num
target_temp = CLAMP(target_temp, min_temp, max_temp)
update_icon()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/list/options = list()
if(istype(W, /obj/item/weapon/reagent_containers/glass))
if(!InputBeaker)
options["install input"] = radial_install_input
if(!OutputBeaker)
options["install output"] = radial_install_output
if(!options || !options.len)
update_icon()
return ..()
var/list/choice = list()
if(length(options) == 1)
for(var/key in options)
choice = key
else
choice = show_radial_menu(user, src, options, require_near = TRUE) // No telekinetics.
switch(choice)
if("install input")
if(!InputBeaker)
user.drop_from_inventory(W)
W.add_fingerprint(user)
W.forceMove(src)
InputBeaker = W
if("install output")
if(!OutputBeaker)
user.drop_from_inventory(W)
W.add_fingerprint(user)
W.forceMove(src)
OutputBeaker = W
update_icon()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/use_power(var/amount, var/chan = -1)
last_power_draw = amount
if(use_cell && cell && cell.charge)
var/cellcharge = cell.charge
cell.use(amount)
var/celldifference = max(0, cellcharge - cell.charge)
amount = celldifference
var/area/A = get_area(src)
if(!A || !isarea(A))
return
if(chan == -1)
chan = power_channel
A.use_power(amount, chan)
/obj/machinery/portable_atmospherics/powered/reagent_distillery/process()
..()
var/run_pump = FALSE
if(InputBeaker || OutputBeaker)
run_pump = TRUE
var/avg_temp = 0
var/avg_pressure = 0
if(connected_port && connected_port.network.line_members.len)
var/list/members = list()
var/datum/pipe_network/Net = connected_port.network
members = Net.line_members.Copy()
for(var/datum/pipeline/Line in members)
avg_pressure += Line.air.return_pressure()
avg_temp += Line.air.temperature
avg_temp /= members.len
avg_pressure /= members.len
if(!powered())
on = FALSE
if(!on || (use_atmos && (!connected_port || avg_pressure < 1000)))
current_temp = round((current_temp + T20C) / 2)
else if(on)
if(!use_atmos)
if(current_temp != round(target_temp))
var/shift_mod = 0
if(current_temp < target_temp)
shift_mod = 1
else if(current_temp > target_temp)
shift_mod = -1
current_temp = CLAMP(round((current_temp + 1 * shift_mod) + (rand(-5, 5) / 10)), min_temp, max_temp)
use_power(power_rating * CELLRATE)
else if(connected_port && avg_pressure > 1000)
current_temp = round((current_temp + avg_temp) / 2)
else if(!run_pump)
visible_message("<span class='notice'>\The [src]'s motors wind down.</span>")
on = FALSE
if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume)
InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20))
if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume)
use_power(power_rating * CELLRATE * 0.5)
Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5))
update_icon()
/obj/machinery/portable_atmospherics/powered/reagent_distillery/update_icon()
..()
cut_overlays()
if(InputBeaker)
add_overlay(overlay_input_beaker)
if(OutputBeaker)
add_overlay(overlay_output_beaker)
if(on)
if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume)
add_overlay(overlay_dumping)
else if(current_temp == round(target_temp))
add_overlay(overlay_ready)
else if(current_temp < target_temp)
add_overlay(overlay_heating)
else
add_overlay(overlay_cooling)
else
add_overlay(overlay_off)
if(connected_port)
add_overlay(overlay_connected)
/*
* Subtypes
*/
/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial
name = "industrial chemical distillery"
desc = "A gas-operated variant of a chemical distillery. Able to reach much higher, and lower, temperatures through the use of treated gas."
use_atmos = TRUE

View File

@@ -44,7 +44,8 @@
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/structure/frame,
/obj/machinery/radiocarbon_spectrometer
/obj/machinery/radiocarbon_spectrometer,
/obj/machinery/portable_atmospherics/powered/reagent_distillery
)
/obj/item/weapon/reagent_containers/glass/Initialize()

View File

@@ -0,0 +1,82 @@
/*
* Patches. A subtype of pills, in order to inherit the possible future produceability within chem-masters, and dissolving.
*/
/obj/item/weapon/reagent_containers/pill/patch
name = "patch"
desc = "A patch."
icon = 'icons/obj/chemical.dmi'
icon_state = null
item_state = "pill"
base_state = "patch"
possible_transfer_amounts = null
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
volume = 60
var/pierce_material = FALSE // If true, the patch can be used through thick material.
/obj/item/weapon/reagent_containers/pill/patch/attack(mob/M as mob, mob/user as mob)
var/mob/living/L = user
if(M == L)
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting))
if(!affecting)
to_chat(user, "<span class='warning'>The limb is missing!</span>")
return
if(affecting.status >= ORGAN_ROBOT)
to_chat(user, "<span class='notice'>\The [src] won't work on a robotic limb!</span>")
return
if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material))
to_chat(user, "<span class='notice'>\The [src] can't be applied through such a thick material!</span>")
return
to_chat(H, "<span class='notice'>\The [src] is placed on your [affecting].</span>")
M.drop_from_inventory(src) //icon update
if(reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH)
qdel(src)
return 1
else if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting))
if(!affecting)
to_chat(user, "<span class='warning'>The limb is missing!</span>")
return
if(affecting.status >= ORGAN_ROBOT)
to_chat(user, "<span class='notice'>\The [src] won't work on a robotic limb!</span>")
return
if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material))
to_chat(user, "<span class='notice'>\The [src] can't be applied through such a thick material!</span>")
return
user.visible_message("<span class='warning'>[user] attempts to place \the [src] onto [H]`s [affecting].</span>")
user.setClickCooldown(user.get_attack_speed(src))
if(!do_mob(user, M))
return
user.drop_from_inventory(src) //icon update
user.visible_message("<span class='warning'>[user] applies \the [src] to [H].</span>")
var/contained = reagentlist()
add_attack_logs(user,M,"Applied a patch containing [contained]")
to_chat(H, "<span class='notice'>\The [src] is placed on your [affecting].</span>")
M.drop_from_inventory(src) //icon update
if(reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH)
qdel(src)
return 1
return 0

View File

@@ -7,6 +7,9 @@
icon = 'icons/obj/chemical.dmi'
icon_state = null
item_state = "pill"
var/base_state = "pill"
possible_transfer_amounts = null
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
@@ -15,7 +18,7 @@
/obj/item/weapon/reagent_containers/pill/Initialize()
. = ..()
if(!icon_state)
icon_state = "pill[rand(1, 4)]" //preset pills only use colour changing or unique icons
icon_state = "[base_state][rand(1, 4)]" //preset pills only use colour changing or unique icons
/obj/item/weapon/reagent_containers/pill/attack(mob/M as mob, mob/user as mob)
if(M == user)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -67,6 +67,7 @@
{{:helper.link('Create pill (60 units max)', null, {'createpill' : 1})}}
{{:helper.link('Create multiple pills', null, {'createpill_multiple' : 1})}}
{{:helper.link('Create bottle (60 units max)', null, {'createbottle' : 1})}}
{{:helper.link('Create patch (60 units max)', null, {'createpatch' : 1})}}
</div>
<div class='item'>
{{:helper.link('', 'pill pill' + data.pillSprite, {'tab_select' : 'pill'}, null, 'link32')}}

View File

@@ -2090,6 +2090,7 @@
#include "code\modules\mob\update_icons.dm"
#include "code\modules\mob\_modifiers\aura.dm"
#include "code\modules\mob\_modifiers\cloning.dm"
#include "code\modules\mob\_modifiers\medical.dm"
#include "code\modules\mob\_modifiers\modifiers.dm"
#include "code\modules\mob\_modifiers\modifiers_misc.dm"
#include "code\modules\mob\_modifiers\traits.dm"
@@ -2851,6 +2852,7 @@
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks_vr.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine_vr.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Modifiers.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Vore_vr.dm"
@@ -2864,6 +2866,8 @@
#include "code\modules\reagents\dispenser\dispenser_presets.dm"
#include "code\modules\reagents\dispenser\dispenser_presets_vr.dm"
#include "code\modules\reagents\dispenser\supply.dm"
#include "code\modules\reagents\distilling\Distilling-Recipes.dm"
#include "code\modules\reagents\distilling\distilling.dm"
#include "code\modules\reagents\reagent_containers\blood_pack.dm"
#include "code\modules\reagents\reagent_containers\blood_pack_vr.dm"
#include "code\modules\reagents\reagent_containers\borghydro.dm"
@@ -2872,6 +2876,7 @@
#include "code\modules\reagents\reagent_containers\glass_vr.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
#include "code\modules\reagents\reagent_containers\hypospray_vr.dm"
#include "code\modules\reagents\reagent_containers\patch.dm"
#include "code\modules\reagents\reagent_containers\pill.dm"
#include "code\modules\reagents\reagent_containers\pill_vr.dm"
#include "code\modules\reagents\reagent_containers\spray.dm"