mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
440 lines
14 KiB
Plaintext
440 lines
14 KiB
Plaintext
#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die
|
|
#define RANDOM_PILL_STYLE 22 //Dont change this one though
|
|
|
|
/obj/machinery/chem_master
|
|
name = "ChemMaster 3000"
|
|
desc = "Used to separate chemicals and distribute them in a variety of forms."
|
|
density = TRUE
|
|
layer = BELOW_OBJ_LAYER
|
|
icon = 'icons/obj/chemical.dmi'
|
|
icon_state = "mixer0"
|
|
use_power = IDLE_POWER_USE
|
|
idle_power_usage = 20
|
|
resistance_flags = FIRE_PROOF | ACID_PROOF
|
|
circuit = /obj/item/circuitboard/machine/chem_master
|
|
var/obj/item/reagent_containers/beaker = null
|
|
var/obj/item/storage/pill_bottle/bottle = null
|
|
var/mode = 1
|
|
var/condi = FALSE
|
|
var/chosenPillStyle = 1
|
|
var/screen = "home"
|
|
var/analyzeVars[0]
|
|
var/useramount = 30 // Last used amount
|
|
var/list/pillStyles
|
|
|
|
/obj/machinery/chem_master/Initialize()
|
|
create_reagents(100)
|
|
|
|
//Calculate the span tags and ids fo all the available pill icons
|
|
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
|
|
pillStyles = list()
|
|
for (var/x in 1 to PILL_STYLE_COUNT)
|
|
var/list/SL = list()
|
|
SL["id"] = x
|
|
SL["htmltag"] = assets.icon_tag("pill[x]")
|
|
pillStyles += list(SL)
|
|
|
|
. = ..()
|
|
|
|
/obj/machinery/chem_master/Destroy()
|
|
QDEL_NULL(beaker)
|
|
QDEL_NULL(bottle)
|
|
return ..()
|
|
|
|
/obj/machinery/chem_master/RefreshParts()
|
|
reagents.maximum_volume = 0
|
|
for(var/obj/item/reagent_containers/glass/beaker/B in component_parts)
|
|
reagents.maximum_volume += B.reagents.maximum_volume
|
|
|
|
/obj/machinery/chem_master/ex_act(severity, target)
|
|
if(severity < 3)
|
|
..()
|
|
|
|
/obj/machinery/chem_master/contents_explosion(severity, target)
|
|
..()
|
|
if(beaker)
|
|
beaker.ex_act(severity, target)
|
|
if(bottle)
|
|
bottle.ex_act(severity, target)
|
|
|
|
/obj/machinery/chem_master/handle_atom_del(atom/A)
|
|
..()
|
|
if(A == beaker)
|
|
beaker = null
|
|
reagents.clear_reagents()
|
|
update_icon()
|
|
else if(A == bottle)
|
|
bottle = null
|
|
|
|
/obj/machinery/chem_master/update_icon()
|
|
cut_overlays()
|
|
if (stat & BROKEN)
|
|
add_overlay("waitlight")
|
|
if(beaker)
|
|
icon_state = "mixer1"
|
|
else
|
|
icon_state = "mixer0"
|
|
|
|
/obj/machinery/chem_master/blob_act(obj/structure/blob/B)
|
|
if (prob(50))
|
|
qdel(src)
|
|
|
|
/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params)
|
|
if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I))
|
|
return
|
|
|
|
else if(default_deconstruction_crowbar(I))
|
|
return
|
|
|
|
if(default_unfasten_wrench(user, I))
|
|
return
|
|
|
|
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
|
|
. = TRUE // no afterattack
|
|
if(panel_open)
|
|
to_chat(user, "<span class='warning'>You can't use the [src.name] while its panel is opened!</span>")
|
|
return
|
|
var/obj/item/reagent_containers/B = I
|
|
if(!user.transferItemToLoc(B, src))
|
|
return
|
|
replace_beaker(user, B)
|
|
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
|
|
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
|
|
to_chat(user, "<span class='notice'>You add [I] into the dispenser slot.</span>")
|
|
updateUsrDialog()
|
|
else
|
|
return ..()
|
|
|
|
/obj/machinery/chem_master/AltClick(mob/living/user)
|
|
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
|
return
|
|
replace_beaker(user)
|
|
return
|
|
|
|
/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
|
|
if(beaker)
|
|
beaker.forceMove(drop_location())
|
|
if(user && Adjacent(user) && !issiliconoradminghost(user))
|
|
user.put_in_hands(beaker)
|
|
if(new_beaker)
|
|
beaker = new_beaker
|
|
else
|
|
beaker = null
|
|
update_icon()
|
|
return TRUE
|
|
|
|
/obj/machinery/chem_master/on_deconstruction()
|
|
replace_beaker(usr)
|
|
if(bottle)
|
|
bottle.forceMove(drop_location())
|
|
adjust_item_drop_location(bottle)
|
|
bottle = null
|
|
return ..()
|
|
|
|
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
|
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
|
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
|
|
assets.send(user)
|
|
ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state)
|
|
ui.open()
|
|
|
|
//Insert our custom spritesheet css link into the html
|
|
/obj/machinery/chem_master/ui_base_html(html)
|
|
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
|
|
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
|
|
|
|
/obj/machinery/chem_master/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["isBeakerLoaded"] = beaker ? 1 : 0
|
|
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
|
|
data["beakerMaxVolume"] = beaker ? beaker.volume : null
|
|
data["mode"] = mode
|
|
data["condi"] = condi
|
|
data["screen"] = screen
|
|
data["analyzeVars"] = analyzeVars
|
|
data["chosenPillStyle"] = chosenPillStyle
|
|
data["isPillBottleLoaded"] = bottle ? 1 : 0
|
|
if(bottle)
|
|
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
|
|
data["pillBotContent"] = bottle.contents.len
|
|
data["pillBotMaxContent"] = STRB.max_items
|
|
|
|
var/beakerContents[0]
|
|
if(beaker)
|
|
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
|
beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
|
data["beakerContents"] = beakerContents
|
|
|
|
var/bufferContents[0]
|
|
if(reagents.total_volume)
|
|
for(var/datum/reagent/N in reagents.reagent_list)
|
|
bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^
|
|
data["bufferContents"] = bufferContents
|
|
|
|
//Calculated at init time as it never changes
|
|
data["pillStyles"] = pillStyles
|
|
|
|
return data
|
|
|
|
/obj/machinery/chem_master/ui_act(action, params)
|
|
if(..())
|
|
return
|
|
switch(action)
|
|
if("eject")
|
|
replace_beaker(usr)
|
|
. = TRUE
|
|
|
|
if("ejectp")
|
|
if(bottle)
|
|
bottle.forceMove(drop_location())
|
|
adjust_item_drop_location(bottle)
|
|
bottle = null
|
|
. = TRUE
|
|
|
|
if("transferToBuffer")
|
|
if(beaker)
|
|
var/id = params["id"]
|
|
var/amount = text2num(params["amount"])
|
|
if (amount > 0)
|
|
end_fermi_reaction()
|
|
beaker.reagents.trans_id_to(src, id, amount)
|
|
. = TRUE
|
|
else if (amount == -1) // -1 means custom amount
|
|
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
|
|
if (useramount > 0)
|
|
end_fermi_reaction()
|
|
beaker.reagents.trans_id_to(src, id, useramount)
|
|
. = TRUE
|
|
|
|
if("transferFromBuffer")
|
|
var/id = params["id"]
|
|
var/amount = text2num(params["amount"])
|
|
if (amount > 0)
|
|
if(mode)
|
|
reagents.trans_id_to(beaker, id, amount)
|
|
. = TRUE
|
|
else
|
|
reagents.remove_reagent(id, amount)
|
|
. = TRUE
|
|
|
|
if("toggleMode")
|
|
mode = !mode
|
|
. = TRUE
|
|
|
|
if("createPill")
|
|
var/many = params["many"]
|
|
if(reagents.total_volume == 0)
|
|
return
|
|
if(!condi)
|
|
var/amount = 1
|
|
var/vol_each = min(reagents.total_volume, 50)
|
|
if(text2num(many))
|
|
amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10)
|
|
if(!amount)
|
|
return
|
|
vol_each = min(reagents.total_volume / amount, 50)
|
|
var/name = stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
|
|
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/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++)
|
|
if(i < drop_threshold)
|
|
P = new(target_loc)
|
|
else
|
|
P = new(drop_location())
|
|
P.name = trim("[name] pill")
|
|
if(chosenPillStyle == RANDOM_PILL_STYLE)
|
|
P.icon_state ="pill[rand(1,21)]"
|
|
else
|
|
P.icon_state = "pill[chosenPillStyle]"
|
|
if(P.icon_state == "pill4")
|
|
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
|
|
adjust_item_drop_location(P)
|
|
reagents.trans_to(P,vol_each)
|
|
else
|
|
var/name = stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN)
|
|
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
|
|
return
|
|
var/obj/item/reagent_containers/food/condiment/pack/P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
|
|
|
|
P.originalname = name
|
|
P.name = trim("[name] pack")
|
|
P.desc = "A small condiment pack. The label says it contains [name]."
|
|
reagents.trans_to(P,10)
|
|
. = TRUE
|
|
|
|
if("pillStyle")
|
|
var/id = text2num(params["id"])
|
|
chosenPillStyle = id
|
|
|
|
if("createPatch")
|
|
var/many = params["many"]
|
|
if(reagents.total_volume == 0)
|
|
return
|
|
var/amount = 1
|
|
var/vol_each = min(reagents.total_volume, 40)
|
|
if(text2num(many))
|
|
amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10)
|
|
if(!amount)
|
|
return
|
|
vol_each = min(reagents.total_volume / amount, 40)
|
|
var/name = stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
|
|
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
|
|
return
|
|
var/obj/item/reagent_containers/pill/P
|
|
|
|
for(var/i = 0; i < amount; i++)
|
|
P = new/obj/item/reagent_containers/pill/patch(drop_location())
|
|
P.name = trim("[name] patch")
|
|
adjust_item_drop_location(P)
|
|
reagents.trans_to(P,vol_each)
|
|
. = TRUE
|
|
|
|
if("createBottle")
|
|
var/many = params["many"]
|
|
if(reagents.total_volume == 0)
|
|
return
|
|
|
|
if(condi)
|
|
var/name = stripped_input(usr, "Name:","Name your bottle!", (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
|
|
var/obj/item/reagent_containers/food/condiment/P = new(drop_location())
|
|
P.originalname = name
|
|
P.name = trim("[name] bottle")
|
|
reagents.trans_to(P, P.volume)
|
|
else
|
|
var/amount_full = 0
|
|
var/vol_part = min(reagents.total_volume, 30)
|
|
if(text2num(many))
|
|
amount_full = round(reagents.total_volume / 30)
|
|
vol_part = reagents.total_volume % 30
|
|
var/name = stripped_input(usr, "Name:","Name your bottle!", (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
|
|
|
|
var/obj/item/reagent_containers/glass/bottle/P
|
|
for(var/i = 0; i < amount_full; i++)
|
|
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
|
|
P.name = trim("[name] bottle")
|
|
adjust_item_drop_location(P)
|
|
reagents.trans_to(P, 30)
|
|
|
|
if(vol_part)
|
|
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
|
|
P.name = trim("[name] bottle")
|
|
adjust_item_drop_location(P)
|
|
reagents.trans_to(P, vol_part)
|
|
. = TRUE
|
|
//CITADEL ADD Hypospray Vials
|
|
if("createVial")
|
|
var/many = params["many"]
|
|
if(reagents.total_volume == 0)
|
|
return
|
|
|
|
var/amount_full = 0
|
|
var/vol_part = min(reagents.total_volume, 30)
|
|
if(text2num(many))
|
|
amount_full = round(reagents.total_volume / 30)
|
|
vol_part = reagents.total_volume % 30
|
|
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
|
|
|
|
var/obj/item/reagent_containers/glass/bottle/vial/small/P
|
|
for(var/i = 0; i < amount_full; i++)
|
|
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)
|
|
|
|
if(vol_part)
|
|
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, vol_part)
|
|
. = TRUE
|
|
//END CITADEL ADDITIONS
|
|
if("analyze")
|
|
var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]]
|
|
if(R)
|
|
var/state = "Unknown"
|
|
if(initial(R.reagent_state) == 1)
|
|
state = "Solid"
|
|
else if(initial(R.reagent_state) == 2)
|
|
state = "Liquid"
|
|
else if(initial(R.reagent_state) == 3)
|
|
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))
|
|
screen = "analyze"
|
|
return
|
|
|
|
if("goScreen")
|
|
screen = params["screen"]
|
|
. = TRUE
|
|
|
|
|
|
|
|
/obj/machinery/chem_master/proc/end_fermi_reaction()//Ends any reactions upon moving.
|
|
if(beaker.reagents.fermiIsReacting)
|
|
beaker.reagents.fermiEnd()
|
|
|
|
/obj/machinery/chem_master/proc/isgoodnumber(num)
|
|
if(isnum(num))
|
|
if(num > 200)
|
|
num = 200
|
|
else if(num < 0)
|
|
num = 0
|
|
else
|
|
num = round(num)
|
|
return num
|
|
else
|
|
return 0
|
|
|
|
|
|
/obj/machinery/chem_master/adjust_item_drop_location(atom/movable/AM) // Special version for chemmasters and condimasters
|
|
if (AM == beaker)
|
|
AM.pixel_x = -8
|
|
AM.pixel_y = 8
|
|
return null
|
|
else if (AM == bottle)
|
|
if (length(bottle.contents))
|
|
AM.pixel_x = -13
|
|
else
|
|
AM.pixel_x = -7
|
|
AM.pixel_y = -8
|
|
return null
|
|
else
|
|
var/md5 = md5(AM.name)
|
|
for (var/i in 1 to 32)
|
|
. += hex2num(md5[i])
|
|
. = . % 9
|
|
AM.pixel_x = ((.%3)*6)
|
|
AM.pixel_y = -8 + (round( . / 3)*8)
|
|
|
|
/obj/machinery/chem_master/condimaster
|
|
name = "CondiMaster 3000"
|
|
desc = "Used to create condiments and other cooking supplies."
|
|
condi = TRUE
|
|
|
|
#undef PILL_STYLE_COUNT
|
|
#undef RANDOM_PILL_STYLE |