"100% functional" commit

This commit is contained in:
Darlantan
2022-09-19 01:18:29 -04:00
parent 542ff5e02f
commit 28ca297677
2 changed files with 164 additions and 147 deletions

View File

@@ -37,6 +37,7 @@
active_power_usage = 150 active_power_usage = 150
anchored = TRUE anchored = TRUE
unacidable = TRUE unacidable = TRUE
density = TRUE
panel_open = TRUE panel_open = TRUE
var/busy = FALSE var/busy = FALSE
@@ -45,7 +46,9 @@
var/delay_modifier = 3 // This is multiplied by the volume of a step to determine how long each step takes. Bigger volume = slower. var/delay_modifier = 3 // 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/obj/item/weapon/reagent_containers/glass/catalyst = null // This is where the user adds catalyst. Usually phoron.
var/list/recipes = list(list()) // This holds chemical recipes up to a maximum determined by SYNTHESIZER_MAX_RECIPES. Two-dimensional. var/list/debug_data // DELETE THIS ONCE DONE TESTNG
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/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. var/list/catalyst_ids = list() // This keeps track of the chemicals in the catalyst to remove before bottling.
var/list/cartridges = list() // Associative, label -> cartridge var/list/cartridges = list() // Associative, label -> cartridge
@@ -221,13 +224,15 @@
data["use_catalyst"] = use_catalyst data["use_catalyst"] = use_catalyst
// Queue and recipe lists might not be formatted correctly here. Delete this once you've confirmed. // Queue and recipe lists might not be formatted correctly here. Delete this once you've confirmed.
data["queue"] = queue var/list/tmp_queue = list()
for(var/i = 1, i <= queue.len, i++)
tmp_queue.Add(list(list("name" = queue[i], "index" = i))) // Thanks byond
data["queue"] = tmp_queue
// Convert the recipes list into an array of strings. The UI does not need the associative list attached to each string. // Convert the recipes list into an array of strings. The UI does not need the associative list attached to each string.
var/list/tmp_recipes = list() var/list/tmp_recipes = list()
if(recipes) for(var/i = 1, i <= recipes.len, i++)
for(var/i = 1, i <= recipes.len, i++) tmp_recipes.Add(list(list("name" = recipes[i])))
tmp_recipes[i] = recipes[i]
data["recipes"] = tmp_recipes data["recipes"] = tmp_recipes
@@ -245,12 +250,20 @@
for(var/datum/reagent/R in catalyst.reagents.reagent_list) for(var/datum/reagent/R in catalyst.reagents.reagent_list)
catalyst_reagents_list[++catalyst_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) catalyst_reagents_list[++catalyst_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id)
if(catalyst)
data["catalystCurrentVolume"] = catalyst.reagents.total_volume
data["catalystMaxVolume"] = catalyst.reagents.maximum_volume
else
data["catalystCurrentVolume"] = null
data["catalystMaxVolume"] = null
var/chemicals[0] var/chemicals[0]
for(var/label in cartridges) for(var/label in cartridges)
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label]
chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list 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["chemicals"] = chemicals
debug_data = data
return data return data
/obj/machinery/chemical_synthesizer/tgui_act(action, params) /obj/machinery/chemical_synthesizer/tgui_act(action, params)
@@ -262,7 +275,7 @@
if("start_queue") if("start_queue")
// Start up the queue. // Start up the queue.
if(!busy) if(!busy)
start_queue() start_queue(usr)
if("rem_queue") if("rem_queue")
// Remove a single entry from the queue. Sanity checks also prevent removing the first entry if the machine is busy though UI should already prevent that. // Remove a single entry from the queue. Sanity checks also prevent removing the first entry if the machine is busy though UI should already prevent that.
var/index = text2num(params["q_index"]) var/index = text2num(params["q_index"])
@@ -303,7 +316,7 @@
if(!busy) if(!busy)
panel_open = !panel_open panel_open = !panel_open
if("mode_toggle") if("mode_toggle")
// Toggles production mode. // Toggles production mode.
production_mode = !production_mode production_mode = !production_mode
if("add_recipe") if("add_recipe")
// Allows the user to add a recipe. Kinda vital for this machine to do anything useful. // Allows the user to add a recipe. Kinda vital for this machine to do anything useful.
@@ -321,11 +334,11 @@
if(confirm == "Yes") if(confirm == "Yes")
var/index = params["rm_index"] var/index = params["rm_index"]
if(index in recipes) if(index in recipes)
recipes -= recipes[index] recipes.Remove(list(index)) // Fuck off Byond.
else else
to_chat(usr, "<span class='warning'>You cannot remove recipes while the machine is running!</span>") to_chat(usr, "<span class='warning'>You cannot remove recipes while the machine is running!</span>")
if("exp_recipe") if("exp_recipe")
// Allows the user to export recipes to chat formatted for easy importing. // Allows the user to export recipes to chat formatted for easy importing.
var/index = params["exp_index"] var/index = params["exp_index"]
export_recipe(usr, index) export_recipe(usr, index)
if("add_queue") if("add_queue")
@@ -336,7 +349,7 @@
var/index = params["qa_index"] var/index = params["qa_index"]
// If you forgot, this is a string returned by the user pressing the "add to queue" button on a recipe. // If you forgot, this is a string returned by the user pressing the "add to queue" button on a recipe.
if(index in recipes) if(index in recipes)
queue[queue.len + 1] = index queue[++queue.len] = index
add_fingerprint(usr) add_fingerprint(usr)
@@ -360,19 +373,23 @@
to_chat(user, "Please provide a unique recipe name!") to_chat(user, "Please provide a unique recipe name!")
return return
var/steps = 2 * CLAMP(round(input(user, "How many steps does your recipe contain (16 max)?", "Steps", null)), 0, RECIPE_MAX_STEPS) // Round to get a whole integer, clamp to ensure proper range. var/steps = 2 * CLAMP(round(input(user, "How many steps does your recipe contain (16 max)?", "Steps", null) as num), 0, RECIPE_MAX_STEPS) // Round to get a whole integer, clamp to ensure proper range.
var/new_rec = list() // This holds the actual recipe. if(!steps)
to_chat(user, "Please input a valid number of steps!")
return
var/list/new_rec = list() // This holds the actual recipe.
for(var/i = 1, i < steps, i += 2) // For the user, 1 step is both text and volume. For list arithmetic, that's 2 steps. for(var/i = 1, i < steps, i += 2) // For the user, 1 step is both text and volume. For list arithmetic, that's 2 steps.
var/label = tgui_input_list(user, "Which chemical would you like to use?", "Chemical Synthesizer", cartridges) var/label = tgui_input_list(user, "Which chemical would you like to use?", "Chemical Synthesizer", cartridges)
if(!label) if(!label)
to_chat(user, "Please select a chemical!") to_chat(user, "Please select a chemical!")
return return
new_rec[i] = label // Add the reagent ID. new_rec[++new_rec.len] = label // Add the reagent ID.
var/amount = CLAMP(round(input(user, "How much of the chemical would you like to add?", "Volume", null)), 0, src.reagents.maximum_volume) var/amount = CLAMP(round(input(user, "How much of the chemical would you like to add?", "Volume", null) as num), 0, src.reagents.maximum_volume)
if(!amount) if(!amount)
to_chat(user, "Please select a volume!") to_chat(user, "Please select a volume!")
return return
new_rec[i+1] = amount // Add the amount of reagent. new_rec[++new_rec.len] = amount // Add the amount of reagent.
recipes[rec_name] = new_rec recipes[rec_name] = new_rec
SStgui.update_uis(src) SStgui.update_uis(src)
@@ -386,18 +403,18 @@
to_chat(user, "Please provide a unique recipe name!") to_chat(user, "Please provide a unique recipe name!")
return return
var/rec_input = input(user, "Input your recipe as 'Chem1,Vol1,Chem2,Vol2,...'", "Import recipe", null) var/rec_input = input(user, "Input your recipe as 'Chem1,vol1,Chem2,vol2,...'", "Import recipe", null)
if(!rec_input || (length(rec_input) > RECIPE_MAX_STRING) || !findtext(rec_input, ",")) // The smallest possible recipe will contain 1 comma. if(!rec_input || (length(rec_input) > RECIPE_MAX_STRING) || !findtext(rec_input, ",")) // The smallest possible recipe will contain 1 comma.
to_chat(user, "Invalid input or recipe max length exceeded!") to_chat(user, "Invalid input or recipe max length exceeded!")
return return
rec_input = trim(rec_input) // Sanitize. rec_input = trim(rec_input) // Sanitize.
var/new_rec = list() // This holds the actual recipe. var/list/new_rec = list() // This holds the actual recipe.
var/vol = FALSE // This tracks if the next step is a chemical name or a volume. var/vol = FALSE // This tracks if the next step is a chemical name or a volume.
var/index = findtext(rec_input, ",") // This tracks the delineation index in the user-provided string. Should never be null at this point. var/index = findtext(rec_input, ",") // This tracks the delineation index in the user-provided string. Should never be null at this point.
var/i = 1 // This tracks the index for new_rec, the actual list which gets added to recipes[rec_name]. var/i = 1 // This tracks the index for new_rec, the actual list which gets added to recipes[rec_name].
while(index) // Alternates between text strings and numbers. When false, the rest of rec_input is the final step. while(index) // Alternates between text strings and numbers. When false, the rest of rec_input is the final step.
new_rec[i] = copytext(rec_input, 1, index) new_rec[++new_rec.len] = copytext(rec_input, 1, index)
if(vol) if(vol)
new_rec[i] = text2num(new_rec[i]) // If it's a volume step, convert to a number. new_rec[i] = text2num(new_rec[i]) // If it's a volume step, convert to a number.
vol = FALSE vol = FALSE
@@ -408,7 +425,7 @@
index = findtext(rec_input, ",") index = findtext(rec_input, ",")
if(rec_input) // The remainder of rec_input should be the final volume step of the recipe. The if() is a sanity check. if(rec_input) // The remainder of rec_input should be the final volume step of the recipe. The if() is a sanity check.
new_rec[i] = text2num(rec_input) new_rec[++new_rec.len] = text2num(rec_input)
recipes[rec_name] = new_rec // Finally, add the recipe to the recipes list. recipes[rec_name] = new_rec // Finally, add the recipe to the recipes list.
SStgui.update_uis(src) SStgui.update_uis(src)
@@ -543,11 +560,11 @@
B.update_icon() B.update_icon()
// Sanity check when manual bottling is triggered. // Sanity check when manual bottling is triggered.
if(queue) if(queue.len)
queue -= queue[1] queue -= queue[1]
// If the queue is now empty, we're done. Otherwise, re-add catalyst and proceed to the next recipe. // If the queue is now empty, we're done. Otherwise, re-add catalyst and proceed to the next recipe.
if(queue) if(queue.len)
if(use_catalyst) if(use_catalyst)
for(var/datum/reagent/chem in catalyst.reagents.reagent_list) for(var/datum/reagent/chem in catalyst.reagents.reagent_list)
catalyst_ids += chem.id catalyst_ids += chem.id
@@ -573,4 +590,4 @@
#undef SYNTHESIZER_MAX_RECIPES #undef SYNTHESIZER_MAX_RECIPES
#undef SYNTHESIZER_MAX_QUEUE #undef SYNTHESIZER_MAX_QUEUE
#undef RECIPE_MAX_STRING #undef RECIPE_MAX_STRING
#undef RECIPE_MAX_STEPS #undef RECIPE_MAX_STEPS

View File

@@ -7,15 +7,22 @@ import { BeakerContents } from './common/BeakerContents';
export const ChemSynthesizer = (props, context) => { export const ChemSynthesizer = (props, context) => {
return ( return (
<Window <Window
width={575} width={1100}
height={500} height={640}
resizable> resizable>
<Window.Content className="Layout__content--flexColumn"> <Window.Content>
<ChemSynthesizerQueueRecipes /> <Flex
<ChemSynthesizerQueueList /> height="100%">
<ChemSynthesizerRecipeList /> <Flex.Item grow={1} maxWidth="33%" >
<ChemSynthesizerChemicals /> <ChemSynthesizerQueueRecipes />
<ChemSynthesizerSettings /> </Flex.Item>
<Flex.Item grow={1}>
<ChemSynthesizerChemicals />
</Flex.Item>
<Flex.Item grow={1}>
<ChemSynthesizerSettings />
</Flex.Item>
</Flex>
</Window.Content> </Window.Content>
</Window> </Window>
); );
@@ -27,6 +34,7 @@ const ChemSynthesizerQueueRecipes = (props, context) => {
busy, busy,
use_catalyst, use_catalyst,
queue = [], queue = [],
recipes = [],
production_mode, production_mode,
} = data; } = data;
@@ -36,15 +44,16 @@ const ChemSynthesizerQueueRecipes = (props, context) => {
width="100%" width="100%"
direction="column"> direction="column">
<Flex.Item <Flex.Item
height={0} maxHeight="50%"
grow={1}> grow={1}
basis={0}>
<Section <Section
height="100%" height="100%"
title="Queue" title="Queue"
overflowY="auto" overflowY="scroll"
buttons={ buttons={
<Fragment> <Fragment>
<Button <Button
disabled={!!busy} disabled={!!busy}
color={use_catalyst ? "green" : "bad"} color={use_catalyst ? "green" : "bad"}
icon="wrench" icon="wrench"
@@ -66,118 +75,93 @@ const ChemSynthesizerQueueRecipes = (props, context) => {
))} ))}
</Fragment> </Fragment>
}> }>
<Flex <LabeledList>
direction="column" {(queue.length && queue.map((item) => {
height="100%"> if ((item.index === 1) && !!busy) {
<Flex.Item> return (
<ChemSynthesizerQueueList /> <LabeledList.Item label={item.name} labelColor="bad">
</Flex.Item> {
</Flex> <Box>
<Button
disabled icon="trash">
Delete
</Button>
</Box>
}
</LabeledList.Item>
);
}
return (
<LabeledList.Item label={item.name}>
<Button
icon="trash"
onClick={() => act("rem_queue", {
q_index: item.index,
})}>
Delete
</Button>
</LabeledList.Item>
);
})) || (
<Box m={1}>
Queue Empty.
</Box>
)}
</LabeledList>
</Section> </Section>
</Flex.Item>
<Flex.Item
maxHeight="50%"
grow={1}
basis={0}>
<Section <Section
height="100%" height="100%"
title="Recipes" title="Recipes"
overflowY="auto" overflowY="scroll"
buttons={ buttons={
<Button <Button
icon="plus" icon="plus"
tooltip={production_mode ? "Import Recipe" : "Generate Recipe"} tooltip={production_mode ? "Import Recipe" : "Generate Recipe"}
onClick={() => act("add_recipe")} /> onClick={() => act("add_recipe")} />
}> }>
<Flex <LabeledList>
direction="column" {(recipes.length && recipes.map((item) => {
height="100%"> return (
<Flex.Item> <LabeledList.Item label={item.name}>
<ChemSynthesizerRecipeList /> <Button
</Flex.Item> icon="plus"
</Flex> tooltip="Add to Queue"
onClick={() => act("add_queue", {
qa_index: item.name,
})} />
<Button
icon="inbox"
tooltip="Export Recipe"
onClick={() => act("exp_recipe", {
exp_index: item.name,
})} />
<Button
color="bad"
icon="minus-circle"
tooltip="Delete Recipe"
disabled={!!busy}
onClick={() => act("rem_recipe", {
rm_index: item.name,
})} />
</LabeledList.Item>
);
})) || (
<Box m={1}>
No recipes found.
</Box>
)}
</LabeledList>
</Section> </Section>
</Flex.Item> </Flex.Item>
</Flex> </Flex>
); );
}; };
const ChemSynthesizerQueueList = (props, context) => {
const { act, data } = useBackend(context);
const {
queue = [],
busy,
} = data;
return (
<LabeledList>
{queue.length && queue.map(item => {
if ((item.index === 1) && !!busy) {
return (
<LabeledList.Item label={item.name} labelColor="bad">
{
<Box>
<Button
disabled icon="trash">
Delete
</Button>
</Box>
}
</LabeledList.Item>
);
return (
<LabeledList.Item label={item.name}>
<Button
icon="trash"
onClick={() => act("rem_queue", {
q_index: item.index,
})}>
Delete
</Button>
</LabeledList.Item>
);
} }) || (
<Box m={1}>
Queue Empty.
</Box>
)}
</LabeledList>
);
};
const ChemSynthesizerRecipeList = (props, context) => {
const { act, data } = useBackend(context);
const {
recipes = [],
busy,
} = data;
return (
<Flex>
{recipes.map(item => {
<Flex.Item>
<Button
color="bad"
icon="minus"
disabled={!!busy}
onClick={() => act("rem_recipe", {
rm_index: item.name,
})} />
<Button
icon="inbox"
onClick={() => act("exp_recipe", {
exp_index: item.name,
})} />
<Button
icon="plus"
onClick={() => act("add_queue", {
qa_index: item.name,
})} />
<Box>
{item.name}
</Box>
</Flex.Item>;
})}
</Flex>
);
};
const ChemSynthesizerChemicals = (props, context) => { const ChemSynthesizerChemicals = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend(context);
const { const {
@@ -185,6 +169,8 @@ const ChemSynthesizerChemicals = (props, context) => {
chemicals = [], chemicals = [],
rxn_vessel = [], rxn_vessel = [],
catalyst, catalyst,
catalystCurrentVolume,
catalystMaxVolume,
catalyst_reagents = [], catalyst_reagents = [],
} = data; } = data;
@@ -193,7 +179,8 @@ const ChemSynthesizerChemicals = (props, context) => {
flexFillers.push(true); flexFillers.push(true);
} }
return ( return (
<Flex> <Flex
direction="column">
<Section <Section
title="Cartridge Reagents" title="Cartridge Reagents"
flexGrow="1"> flexGrow="1">
@@ -203,11 +190,16 @@ const ChemSynthesizerChemicals = (props, context) => {
height="100%" height="100%"
align="flex-start"> align="flex-start">
{chemicals.map((c, i) => ( {chemicals.map((c, i) => (
<Flex.Item key={i} grow="1" m={0.2} basis="40%" height="20px"> <Flex.Item key={i} grow="1" m={0.2} basis="40%" height="20px">
<Box> <Button
{c.title + " (" + c.amount + ")"} icon="arrow-circle-down"
</Box> width="100%"
</Flex.Item> height="100%"
align="flex-start"
disabled={1}
content={c.title + ' (' + c.amount + ')'}
/>
</Flex.Item>
))} ))}
{flexFillers.map((_, i) => ( {flexFillers.map((_, i) => (
<Flex.Item key={i} grow="1" basis="25%" height="20px" /> <Flex.Item key={i} grow="1" basis="25%" height="20px" />
@@ -235,9 +227,9 @@ const ChemSynthesizerChemicals = (props, context) => {
minHeight="25%" minHeight="25%"
buttons={( buttons={(
<Box> <Box>
{!!beaker && ( {!!catalyst && (
<Box inline color="label" mr={2}> <Box inline color="label" mr={2}>
{beakerCurrentVolume} / {beakerMaxVolume} units {catalystCurrentVolume} / {catalystMaxVolume} units
</Box> </Box>
)} )}
<Button <Button
@@ -277,20 +269,25 @@ const ChemSynthesizerSettings = (props, context) => {
<Section <Section
height="100%" height="100%"
title="Settings" title="Settings"
overflowY="auto" overflowY="auto">
buttons={ <Flex
<Fragment> direction="column">
<Button <Flex.Item>
<Button
color={production_mode ? "green" : "bad"} color={production_mode ? "green" : "bad"}
icon="wrench" icon="wrench"
content={production_mode ? "Recipe mode: Import" : "Recipe mode: Tutorial"} content={production_mode ? "Recipe mode: Import" : "Recipe mode: Tutorial"}
onClick={() => act("panel_toggle")} /> onClick={() => act("mode_toggle")} />
<Button </Flex.Item>
<Flex.Item>
<Button
disabled={!!busy} disabled={!!busy}
color={panel_open ? "bad" : "green"} color={panel_open ? "bad" : "green"}
icon="wrench" icon="wrench"
content={panel_open ? "Panel Open" : "Panel Closed"} content={panel_open ? "Panel Open" : "Panel Closed"}
onClick={() => act("panel_toggle")} /> onClick={() => act("panel_toggle")} />
</Flex.Item>
<Flex.Item>
{(!busy && ( {(!busy && (
<Button <Button
disabled={!rxn_vessel.length} disabled={!rxn_vessel.length}
@@ -300,15 +297,18 @@ const ChemSynthesizerSettings = (props, context) => {
content="Bottle Manually" content="Bottle Manually"
onClick={() => act("bottle_product")} /> onClick={() => act("bottle_product")} />
))} ))}
</Flex.Item>
<Flex.Item>
<Button <Button
disabled={!busy} disabled={!busy}
color="bad" color="bad"
icon="minus-circle" icon="minus-circle"
content="EMERGENCY STOP" content="EMERGENCY STOP"
onClick={() => act("emergency_stop")} /> onClick={() => act("emergency_stop")} />
</Fragment> </Flex.Item>
} /> </Flex>
</Section>
</Flex.Item> </Flex.Item>
</Flex> </Flex>
); );
}; };