Adds bottles, pills, patches, and fixes emergency stop

This commit is contained in:
Darlantan
2022-11-02 22:24:30 -04:00
parent 9f8d6f289d
commit 65bfa8d415
5 changed files with 207 additions and 15 deletions

View File

@@ -54,8 +54,9 @@ var/list/cheartstopper = list("potassium_chloride") // Thi
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
#define MAX_PATCH_SPRITE 4 //max icon state of the patch sprites, CHOMPedit
#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once
#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill
#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch
#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume)
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever

View File

@@ -473,6 +473,9 @@
for(var/i = 1 to 4)
assets["bottle-[i].png"] = icon('icons/obj/chemical.dmi', "bottle-[i]")
for(var/i = 1 to 4) // CHOMPedit
assets["patch[i].png"] = icon('icons/obj/chemical.dmi', "patch[i]") // CHOMPedit
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])

View File

@@ -23,9 +23,15 @@
var/busy = FALSE
var/production_mode = FALSE // Toggle between click-step input and comma-delineated text input for creating recipes.
var/use_catalyst = TRUE // Determines whether or not the catalyst will be added to reagents while processing a recipe.
var/stalled = FALSE // Required for emergency stop to interrupt on-going recipes.
var/drug_substance = 1 // Controls which form medicine takes (bottle, pill, etc). 1 for bottle, 2 for pill, 3 for patch.
var/delay_modifier = 4 // This is multiplied by the volume of a step to determine how long each step takes. Bigger volume = slower.
var/obj/item/weapon/reagent_containers/glass/catalyst = null // This is where the user adds catalyst. Usually phoron.
var/bottle_icon = 4 // Determines icon states of bottles, pills, and patches.
var/pill_icon = 2
var/patch_icon = 2
var/list/recipes = list() // This holds chemical recipes up to a maximum determined by SYNTHESIZER_MAX_RECIPES. Two-dimensional.
var/list/queue = list() // This holds the recipe id's for queued up recipes.
var/list/catalyst_ids = list() // This keeps track of the chemicals in the catalyst to remove before bottling.
@@ -264,6 +270,10 @@
data["production_mode"] = production_mode
data["panel_open"] = panel_open
data["use_catalyst"] = use_catalyst
data["drug_substance"] = drug_substance
data["bottle_icon"] = bottle_icon
data["pill_icon"] = pill_icon
data["patch_icon"] = patch_icon
var/list/tmp_queue = list()
for(var/i = 1, i <= queue.len, i++)
@@ -304,12 +314,19 @@
chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list
data["chemicals"] = chemicals
data["modal"] = tgui_modal_data(src)
return data
/obj/machinery/chemical_synthesizer/tgui_act(action, params)
/obj/machinery/chemical_synthesizer/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
if(tgui_act_modal(action, params, ui, state))
return TRUE
add_fingerprint(usr)
. = TRUE
switch(action)
if("start_queue")
@@ -347,7 +364,7 @@
if(busy)
var/confirm = alert(usr, "Are you sure you want to stall the machine?", "Confirm", "Yes", "No")
if(confirm == "Yes")
stall()
stalled = TRUE
if("bottle_product")
// Bottles the reaction mixture if stalled.
if(!busy)
@@ -391,8 +408,56 @@
// If you forgot, this is a string returned by the user pressing the "add to queue" button on a recipe.
if(index in recipes)
queue[++queue.len] = index
if("drug_form")
// Toggles between bottles, pills, and patches.
drug_substance = params["drug_index"]
add_fingerprint(usr)
/obj/machinery/chemical_synthesizer/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state)
. = TRUE
var/id = params["id"] // The modal's ID
var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"]
switch(tgui_modal_act(src, action, params))
if(TGUI_MODAL_OPEN)
switch(id)
if("change_pill_style")
var/list/choices = list()
for(var/i = 1 to MAX_PILL_SPRITE)
choices += "pill[i].png"
tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pill_icon, choices)
if("change_patch_style")
var/list/choices = list()
for(var/i = 1 to MAX_PATCH_SPRITE)
choices += "patch[i].png"
tgui_modal_bento(src, id, "Please select the new style for patches:", null, arguments, patch_icon, choices)
if("change_bottle_style")
var/list/choices = list()
for(var/i = 1 to MAX_BOTTLE_SPRITE)
choices += "bottle-[i].png"
tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottle_icon, choices)
else
return FALSE
if(TGUI_MODAL_ANSWER)
var/answer = params["answer"]
switch(id)
if("change_pill_style")
var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE)
if(!new_style)
return
pill_icon = new_style
if("change_patch_style")
var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PATCH_SPRITE)
if(!new_style)
return
patch_icon = new_style
if("change_bottle_style")
var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE)
if(!new_style)
return
bottle_icon = new_style
else
return FALSE
else
return FALSE
/obj/machinery/chemical_synthesizer/attack_ghost(mob/user)
if(stat & (BROKEN|NOPOWER))
@@ -482,6 +547,9 @@
// This proc handles adding the catalyst starting the synthesizer's queue.
/obj/machinery/chemical_synthesizer/proc/start_queue(mob/user)
if(stalled) // Incase SOMEHOW this var is true when the machine isn't running.
stalled = FALSE
if(stat & (BROKEN|NOPOWER))
return
@@ -518,6 +586,11 @@
// This proc controls the timing for each step in a reaction. Step is the index for the current chem of our recipe, step + 1 is the volume of said chem.
/obj/machinery/chemical_synthesizer/proc/follow_recipe(var/r_id, var/step as num)
if(stalled) // Emergency stop if() check.
stalled = FALSE
stall()
return
if(stat & (BROKEN|NOPOWER))
stall()
return
@@ -530,6 +603,11 @@
// This proc carries out the actual steps in each reaction.
/obj/machinery/chemical_synthesizer/proc/perform_reaction(var/r_id, var/step as num)
if(stalled) // Emergency stop if() check.
stalled = FALSE
stall()
return
if(stat & (BROKEN|NOPOWER))
stall()
return
@@ -593,14 +671,41 @@
if(!r_id)
r_id = "[reagents.get_master_reagent_name()]"
while(reagents.total_volume)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(src.loc)
B.name = "[r_id] bottle"
B.pixel_x = rand(-7, 7) // random position
B.pixel_y = rand(-7, 7)
B.icon_state = "bottle-4"
reagents.trans_to_obj(B, min(reagents.total_volume, MAX_UNITS_PER_BOTTLE))
B.update_icon()
// Copy-pasta go brr
switch(drug_substance)
if(2) // Pills
while(reagents.total_volume)
var/obj/item/weapon/reagent_containers/pill/P= new(src.loc)
P.name = "[r_id]"
P.pixel_x = rand(-7, 7) // random position
P.pixel_y = rand(-7, 7)
P.icon_state = "pill[pill_icon]"
reagents.trans_to_obj(P, min(reagents.total_volume, MAX_UNITS_PER_PILL))
if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent
P.color = P.reagents.get_color()
P.update_icon()
if(3) // Patches
while(reagents.total_volume)
var/obj/item/weapon/reagent_containers/pill/patch/P= new(src.loc)
P.name = "[r_id]"
P.pixel_x = rand(-7, 7) // random position
P.pixel_y = rand(-7, 7)
P.icon_state = "patch[patch_icon]"
reagents.trans_to_obj(P, min(reagents.total_volume, MAX_UNITS_PER_PATCH))
if(P.icon_state in list("patch1", "patch2", "patch3", "patch4")) // if using greyscale, take colour from reagent
P.color = P.reagents.get_color()
P.update_icon()
else // Bottles. Official value is 1, but this works as a sanity check.
while(reagents.total_volume)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(src.loc)
B.name = "[r_id] bottle"
B.pixel_x = rand(-7, 7) // random position
B.pixel_y = rand(-7, 7)
B.icon_state = "bottle-[bottle_icon]"
reagents.trans_to_obj(B, min(reagents.total_volume, MAX_UNITS_PER_BOTTLE))
B.update_icon()
// Sanity check when manual bottling is triggered.
if(queue.len)

View File

@@ -3,10 +3,12 @@ import { useBackend } from '../backend';
import { Box, Button, Flex, LabeledList, Section } from '../components';
import { Window } from '../layouts';
import { BeakerContents } from './common/BeakerContents';
import { ComplexModal, modalOpen } from './common/ComplexModal';
export const ChemSynthesizer = (props, context) => {
return (
<Window width={1100} height={640} resizable>
<ComplexModal />
<Window.Content>
<Flex height="100%">
<Flex.Item grow={1} maxWidth="33%">
@@ -15,7 +17,7 @@ export const ChemSynthesizer = (props, context) => {
<Flex.Item grow={1}>
<ChemSynthesizerChemicals />
</Flex.Item>
<Flex.Item grow={1}>
<Flex.Item grow={1} maxWidth="33%">
<ChemSynthesizerSettings />
</Flex.Item>
</Flex>
@@ -212,7 +214,7 @@ const ChemSynthesizerChemicals = (props, context) => {
const ChemSynthesizerSettings = (props, context) => {
const { act, data } = useBackend(context);
const { busy, production_mode, panel_open, rxn_vessel } = data;
const { busy, production_mode, panel_open, rxn_vessel, drug_substance, bottle_icon, pill_icon, patch_icon } = data;
return (
<Flex height="100%" width="100%" direction="column">
@@ -260,6 +262,87 @@ const ChemSynthesizerSettings = (props, context) => {
</Flex>
</Section>
</Flex.Item>
<Flex.Item height={0} grow={1}>
<Section height="100%" title="Drug Substance" overflowY="auto">
<LabeledList>
<LabeledList.Item label="Bottle">
<Button
icon="wine-bottle"
content="Activate"
selected={data.drug_substance === 1}
mr="0.5rem"
onClick={() => act('drug_form', { drug_index: 1 })}
/>
<Button onClick={() => modalOpen(context, 'change_bottle_style')}>
<div
style={
'display: inline-block;' +
'width: 16px;' +
'height: 16px;' +
'vertical-align: middle;' +
'background: url(bottle-' +
data.bottle_icon +
'.png);' +
'background-size: 200%;' +
'background-position: left -10px bottom -6px;'
}
/>
Style
</Button>
</LabeledList.Item>
<LabeledList.Item label="Pill">
<Button
icon="circle"
content="Activate"
selected={data.drug_substance === 2}
mr="0.5rem"
onClick={() => act('drug_form', { drug_index: 2 })}
/>
<Button onClick={() => modalOpen(context, 'change_pill_style')}>
<div
style={
'display: inline-block;' +
'width: 16px;' +
'height: 16px;' +
'vertical-align: middle;' +
'background: url(pill' +
data.pill_icon +
'.png);' +
'background-size: 200%;' +
'background-position: left -10px bottom -6px;'
}
/>
Style
</Button>
</LabeledList.Item>
<LabeledList.Item label="Patch">
<Button
icon="square"
content="Activate"
selected={data.drug_substance === 3}
mr="0.5rem"
onClick={() => act('drug_form', { drug_index: 3 })}
/>
<Button onClick={() => modalOpen(context, 'change_patch_style')}>
<div
style={
'display: inline-block;' +
'width: 16px;' +
'height: 16px;' +
'vertical-align: middle;' +
'background: url(patch' +
data.patch_icon +
'.png);' +
'background-size: 200%;' +
'background-position: left -10px bottom -6px;'
}
/>
Style
</Button>
</LabeledList.Item>
</LabeledList>
</Section>
</Flex.Item>
</Flex>
);
};

File diff suppressed because one or more lines are too long