Fixing things and gui

This commit is contained in:
Fermi
2021-01-04 01:48:35 +00:00
parent b3c1c69861
commit 37c3bbbd9c
8 changed files with 246 additions and 53 deletions

View File

@@ -973,10 +973,8 @@
for(var/A in cached_reagents)
var/datum/reagent/R = A
if (R.type == reagent)
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
pH = REAGENT_NORMAL_PH
//In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people.
else if (!ignore_pH)
if(!ignore_pH)
//if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7)))
pH = (((pH - R.pH) / total_volume) * amount) + pH
if(istype(my_atom, /obj/item/reagent_containers/))
@@ -987,6 +985,8 @@
amount = clamp(amount, 0, R.volume)
R.volume -= amount
update_total()
if(total_volume <= 0)//Because this can result in 0, I don't want it to crash.
pH = REAGENT_NORMAL_PH
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
if(my_atom)

View File

@@ -24,6 +24,7 @@
circuit = /obj/item/circuitboard/machine/chem_dispenser
var/obj/item/stock_parts/cell/cell
var/powerefficiency = 0.0666666
var/dispenceUnit = 5
var/amount = 30
var/recharge_amount = 10
var/recharge_counter = 0
@@ -32,6 +33,7 @@
var/nopower_state = "dispenser_nopower"
var/has_panel_overlay = TRUE
var/obj/item/reagent_containers/beaker = null
var/list/stored_beakers = list()
var/list/dispensable_reagents = list(
/datum/reagent/hydrogen,
/datum/reagent/lithium,
@@ -58,7 +60,9 @@
/datum/reagent/silver,
/datum/reagent/iodine,
/datum/reagent/bromine,
/datum/reagent/stable_plasma
/datum/reagent/stable_plasma,
/datum/reagent/fermi/acidic_buffer/weak,
/datum/reagent/fermi/basic_buffer/weak
)
//These become available once upgraded.
var/list/upgrade_reagents = list(
@@ -102,6 +106,7 @@
if(upgrade_reagents3)
upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc)
dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc)
create_reagents(200, NO_REACT)
update_icon()
/obj/machinery/chem_dispenser/Destroy()
@@ -190,13 +195,16 @@
data["amount"] = amount
data["energy"] = cell.charge ? cell.charge * powerefficiency : "0" //To prevent NaN in the UI.
data["maxEnergy"] = cell.maxcharge * powerefficiency
data["storedVol"] = reagents.total_volume
data["maxVol"] = reagents.maximum_volume
data["isBeakerLoaded"] = beaker ? 1 : 0
data["stepAmount"] = dispenceUnit
var/beakerContents[0]
var/beakerCurrentVolume = 0
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
beakerContents.Add(list(list("name" = R.name, "id" = R.type, "volume" = R.volume))) // list in a list because Byond merges the first list...
beakerCurrentVolume += R.volume
data["beakerContents"] = beakerContents
@@ -204,10 +212,9 @@
data["beakerCurrentVolume"] = beakerCurrentVolume
data["beakerMaxVolume"] = beaker.volume
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
data["beakerCurrentpH"] = beaker.reagents.pH
//pH accuracy
for(var/obj/item/stock_parts/capacitor/C in component_parts)
data["partRating"]= 10**(C.rating-1)
data["beakerCurrentpH"] = round(beaker.reagents.pH, 10**-(C.rating+1))
else
data["beakerCurrentVolume"] = null
@@ -225,11 +232,17 @@
var/chemname = temp.name
if(is_hallucinating && prob(5))
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name))))
chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name), "pH" = temp.pH, "pHCol" = ConvertpHToCol(temp.pH))))
data["chemicals"] = chemicals
data["recipes"] = saved_recipes
data["recordingRecipe"] = recording_recipe
var/storedContents[0]
if(reagents.total_volume)
for(var/datum/reagent/N in reagents.reagent_list)
storedContents.Add(list(list("name" = N.name, "id" = N.type, "volume" = N.volume)))
data["storedContents"] = storedContents
return data
/obj/machinery/chem_dispenser/ui_act(action, params)
@@ -240,10 +253,9 @@
if(!is_operational() || QDELETED(beaker))
return
var/target = text2num(params["target"])
if(target in beaker.possible_transfer_amounts)
amount = target
work_animation()
. = TRUE
SetAmount(target)
work_animation()
. = TRUE
if("dispense")
if(!is_operational() || QDELETED(cell))
return
@@ -268,10 +280,9 @@
if(!is_operational() || recording_recipe)
return
var/amount = text2num(params["amount"])
if(beaker && (amount in beaker.possible_transfer_amounts))
beaker.reagents.remove_all(amount)
work_animation()
. = TRUE
beaker.reagents.remove_all(amount) //This should be set correctly in "amount"
work_animation()
. = TRUE
if("eject")
replace_beaker(usr)
. = TRUE
@@ -338,6 +349,48 @@
recording_recipe = null
. = TRUE
//Storing and unstoring reagents
if("store")
if(!is_operational() || QDELETED(cell))
return
if(!beaker)
return
if(recording_recipe)
say("Cannot store while recording!")
return
if(beaker.reagents.fermiIsReacting)
say("Cannot store ongoing reactions!")
return
var/reagent = text2path(params["id"])
var/datum/reagent/R = beaker.reagents.has_reagent(reagent)
if(reagents.total_volume+amount > reagents.maximum_volume)
say("Not enough storage space left!")
return
beaker.reagents.trans_id_to(src, R.type, amount)
work_animation()
. = TRUE
if("unstore")
if(!is_operational() || QDELETED(cell))
return
if(!beaker)
return
if(recording_recipe)
say("Cannot distribute while recording!")
return
var/reagent = text2path(params["id"])
var/datum/reagent/R = reagents.has_reagent(reagent)
reagents.trans_id_to(beaker, R.type, amount)
work_animation()
. = TRUE
/obj/machinery/chem_dispenser/proc/SetAmount(inputAmount)
if(inputAmount % 5 == 0) //Always allow 5u values
amount = inputAmount
return
inputAmount -= inputAmount % dispenceUnit
amount = inputAmount
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I))
return
@@ -390,6 +443,8 @@
cell = P
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
newpowereff += 0.0166666666*M.rating
if(reagents)
reagents.maximum_volume = 200*(M.rating+1)
for(var/obj/item/stock_parts/capacitor/C in component_parts)
recharge_amount *= C.rating
for(var/obj/item/stock_parts/manipulator/M in component_parts)
@@ -399,6 +454,15 @@
dispensable_reagents |= upgrade_reagents2
if(M.rating > 3)
dispensable_reagents |= upgrade_reagents3
switch(M.rating)
if(0)
dispenceUnit = 5
if(1)
dispenceUnit = 3
if(2)
dispenceUnit = 2
if(3 to INFINITY)
dispenceUnit = 1
powerefficiency = round(newpowereff, 0.01)
/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
@@ -409,6 +473,8 @@
user.put_in_hands(B)
if(new_beaker)
beaker = new_beaker
if(amount > beaker.reagents.maximum_volume)
amount = beaker.reagents.maximum_volume
else
beaker = null
update_icon()
@@ -427,6 +493,32 @@
replace_beaker(user)
return TRUE
/obj/machinery/chem_dispenser/proc/ConvertpHToCol(pH)
switch(pH)
if(-INFINITY to 1)
return "red"
if(1 to 2)
return "orange"
if(2 to 3)
return "average"
if(3 to 4)
return "yellow" //yellow looks really bad for some reason
if(4 to 5)
return "olive"
if(5 to 6)
return "good"
if(6 to 8)
return "green"
if(8 to 9.5)
return "teal"
if(9.5 to 11)
return "blue"
if(11 to 12.5)
return "violet"
if(12.5 to INFINITY)
return "purple"
/obj/machinery/chem_dispenser/drinks/Initialize()
. = ..()
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE)
@@ -453,6 +545,7 @@
b_o.pixel_y = -7
b_o.pixel_x = rand(-9, 9)
return b_o
/obj/machinery/chem_dispenser/drinks
name = "soda dispenser"

View File

@@ -126,7 +126,7 @@
var beakerContents[0]
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume, "purity" = R.purity))) // list in a list because Byond merges the first list...
beakerContents.Add(list(list("name" = R.name, "volume" = round(R.volume, 0.01), "purity" = round(R.purity, 0.01)))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
return data

View File

@@ -184,13 +184,13 @@
var/beakerContents[0]
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume))) // list in a list because Byond merges the first list...
beakerContents.Add(list(list("name" = R.name, "id" = R.type, "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" = ckey(N.name), "volume" = N.volume))) // ^
bufferContents.Add(list(list("name" = N.name, "id" = N.type, "volume" = N.volume))) // ^
data["bufferContents"] = bufferContents
//Calculated at init time as it never changes
@@ -216,7 +216,7 @@
if(action == "transfer")
if(!beaker)
return FALSE
var/reagent = GLOB.name2reagent[params["id"]]
var/reagent = text2path(params["id"])
var/amount = text2num(params["amount"])
var/to_container = params["to"]
// Custom amount
@@ -386,7 +386,7 @@
if(action == "analyze")
// var/datum/reagent/R = GLOB.name2reagent[params["id"]]
var/reagent = GLOB.name2reagent[params["id"]]
var/reagent = text2path(params["id"])
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent]
if(R)
var/state = "Unknown"
@@ -405,7 +405,7 @@
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" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "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))
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" = R.purity)
screen = "analyze"
return TRUE

View File

@@ -117,6 +117,8 @@
if(St.purity < 1)
St.volume *= St.purity
St.purity = 1
if(!N)
return
var/amount = clamp(0.002, 0, N.volume)
N.volume -= amount
St.data["grown_volume"] = St.data["grown_volume"] + added_volume

View File

@@ -335,11 +335,13 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume)
holder.clear_reagents()
/datum/reagent/fermi/acidic_buffer
name = "Acidic buffer"
name = "Potent acidic buffer"
description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another."
color = "#fbc314"
pH = 0
chemical_flags = REAGENT_FORCEONNEW
can_synth = TRUE
var/strength = 2
//Consumes self on addition and shifts pH
/datum/reagent/fermi/acidic_buffer/on_new(datapH)
@@ -348,18 +350,36 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume)
data = datapH
if(LAZYLEN(holder.reagent_list) == 1)
return ..()
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
holder.pH = ((holder.pH * (holder.total_volume-volume))+(pH * (volume*strength)))/(holder.total_volume + volume)
holder.my_atom.visible_message("<span class='warning'>The beaker fizzes as the pH changes!</b></span>")
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
holder.remove_reagent(type, volume, ignore_pH = TRUE)
..()
/datum/reagent/fermi/acidic_buffer/weak
name = "Acidic buffer"
description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another."
color = "#fbf344"
pH = 4
can_synth = TRUE
strength = 0.4
/datum/reagent/fermi/basic_buffer
name = "Basic buffer"
name = "Potent basic buffer"
description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another."
color = "#3853a4"
pH = 14
chemical_flags = REAGENT_FORCEONNEW
can_synth = TRUE
var/strength = 2
/datum/reagent/fermi/basic_buffer/weak
name = "Basic buffer"
description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another."
color = "#5873c4"
pH = 10
can_synth = TRUE
strength = 0.4
/datum/reagent/fermi/basic_buffer/on_new(datapH)
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
@@ -367,7 +387,7 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume)
data = datapH
if(LAZYLEN(holder.reagent_list) == 1)
return ..()
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
holder.pH = ((holder.pH * (holder.total_volume-volume))+(pH * (volume*strength)))/(holder.total_volume + volume)
holder.my_atom.visible_message("<span class='warning'>The beaker froths as the pH changes!</b></span>")
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
holder.remove_reagent(type, volume, ignore_pH = TRUE)

View File

@@ -1,13 +1,18 @@
import { toFixed } from 'common/math';
import { toTitleCase } from 'common/string';
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { AnimatedNumber, Box, Button, Icon, LabeledList, ProgressBar, Section } from '../components';
import { useBackend, useLocalState } from '../backend';
import { AnimatedNumber, Box, Button, Icon, LabeledList, ProgressBar, Section, Table, NumberInput } from '../components';
import { Window } from '../layouts';
export const ChemDispenser = (props, context) => {
const { act, data } = useBackend(context);
const recording = !!data.recordingRecipe;
const [hasCol, setHasCol] = useLocalState(
context, 'fs_title', false);
const {
storedContents = [],
} = data;
// TODO: Change how this piece of shit is built on server side
// It has to be a list, not a fucking OBJECT!
const recipes = Object.keys(data.recipes)
@@ -28,7 +33,7 @@ export const ChemDispenser = (props, context) => {
return (
<Window
width={565}
height={620}
height={680}
resizable>
<Window.Content scrollable>
<Section
@@ -105,16 +110,22 @@ export const ChemDispenser = (props, context) => {
<Section
title="Dispense"
buttons={(
beakerTransferAmounts.map(amount => (
<Button
key={amount}
icon="plus"
selected={amount === data.amount}
content={amount}
onClick={() => act('amount', {
[<NumberInput
width="65px"
unit="u"
step={data.stepAmount}
stepPixelSize={data.stepAmount}
value={data.amount}
minValue={0}
maxValue={data.beakerMaxVolume}
onDrag={(e, amount) => act('amount', {
target: amount,
})} />
))
})} />,
<Button icon="cog"
tooltip="Color code the reagents by pH"
tooltipPosition="bottom-left"
selected={hasCol}
onClick={() => setHasCol(!hasCol)} />]
)}>
<Box mr={-1}>
{data.chemicals.map(chemical => (
@@ -124,12 +135,29 @@ export const ChemDispenser = (props, context) => {
width="129.5px"
lineHeight={1.75}
content={chemical.title}
tooltip={"pH: "+chemical.pH}
color={hasCol ? chemical.pHCol : "blue"}
onClick={() => act('dispense', {
reagent: chemical.id,
})} />
))}
</Box>
</Section>
<Section
title="Storage">
<ProgressBar
value={data.storedVol / data.maxVol}>
{toFixed(data.storedVol) + ' units'}
</ProgressBar>
<ChemicalBuffer>
{storedContents.map(chemical => (
<ChemicalBufferEntry
key={chemical.id}
chemical={chemical}
transferTo="beaker" />
))}
</ChemicalBuffer>
</Section>
<Section
title="Beaker"
buttons={(
@@ -171,17 +199,14 @@ export const ChemDispenser = (props, context) => {
{(!data.isBeakerLoaded && !recording) && 'N/A'
|| beakerContents.length === 0 && 'Nothing'}
</Box>
{beakerContents.map(chemical => (
<Box
key={chemical.name}
color="label">
<AnimatedNumber
initial={0}
value={chemical.volume} />
{' '}
units of {chemical.name}
</Box>
))}
<ChemicalBeaker>
{beakerContents.map(chemical => (
<ChemicalBeakerEntry
key={chemical.id}
chemical={chemical}
transferTo="beaker" />
))}
</ChemicalBeaker>
<Box
key={"pH"}>
pH:
@@ -196,3 +221,56 @@ export const ChemDispenser = (props, context) => {
</Window>
);
};
const ChemicalBuffer = Table;
const ChemicalBufferEntry = (props, context) => {
const { act } = useBackend(context);
const { chemical, transferTo } = props;
return (
<Table.Row key={chemical.id}>
<Table.Cell color="label">
<AnimatedNumber
value={chemical.volume}
initial={0} />
{` units of ${chemical.name}`}
</Table.Cell>
<Table.Cell collapsing>
<Button
content="Dispense"
icon="download"
mt={0.5}
onClick={() => act('unstore', {
id: chemical.id,
})} />
</Table.Cell>
</Table.Row>
);
};
const ChemicalBeaker = Table;
const ChemicalBeakerEntry = (props, context) => {
const { act } = useBackend(context);
const { chemical, transferTo } = props;
return (
<Table.Row key={chemical.id}>
<Table.Cell color="label">
<AnimatedNumber
value={chemical.volume}
initial={0} />
{` units of ${chemical.name}`}
</Table.Cell>
<Table.Cell collapsing>
<Button
content="Store"
icon="upload"
mt={0.5}
onClick={() => act('store', {
id: chemical.id,
})} />
</Table.Cell>
</Table.Row>
);
};

View File

@@ -400,11 +400,11 @@ const AnalysisResults = (props, context) => {
<LabeledList.Item label="Addiction Threshold">
{analyzeVars.addicD}
</LabeledList.Item>
{!!fermianalyze && ( // why did you do that before? it's fucking bad.
<LabeledList.Item label="Purity">
{analyzeVars.purityF}
</LabeledList.Item>
{!! data.fermianalyze && ( // why did you do that before? it's fucking bad.
<Fragment>
<LabeledList.Item label="Purity">
{analyzeVars.purityF}
</LabeledList.Item>
<LabeledList.Item label="Inverse Ratio">
{analyzeVars.inverseRatioF}
</LabeledList.Item>