Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smartfridge tgui #1623

Merged
merged 13 commits into from
Dec 10, 2022
375 changes: 210 additions & 165 deletions code/game/machinery/kitchen/smartfridge.dm

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions code/modules/reagents/chemical_research/Chemical-Research.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ var/global/datum/chemical_data/chemical_data = new /datum/chemical_data/
var/list/chemical_networks = list()
var/list/shared_item_storage = list()
var/list/shared_item_quantity = list()

var/list/chemical_objective_list = list() //List of all objective reagents indexed by ID associated with the objective value
var/list/chemical_not_completed_objective_list = list() //List of not completed objective reagents indexed by ID associated with the objective value
var/list/chemical_identified_list = list() //List of all identified objective reagents indexed by ID associated with the objective value


/datum/chemical_data/proc/update_credits(var/change)
rsc_credits = max(0, rsc_credits + change)

Expand Down
4 changes: 3 additions & 1 deletion code/modules/reagents/chemistry_machinery/autodispenser.dm
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@
if(smartlink && linked_storage)
var/skip
for(var/obj/item/reagent_container/C in linked_storage.contents)
if(!C.reagents)
continue
var/O = C.reagents.get_reagent_amount(R.id)
if(O)
//Check if there's enough and note if there isn't, then transfer
Expand Down Expand Up @@ -381,7 +383,7 @@
P.amount_per_transfer_from_this = 60
reagents.trans_to(P, 60)
if(!linked_storage.add_network_item(P)) // Prefer network to avoid recursion (create bottle, then consume from bottle)
linked_storage.add_item(P)
linked_storage.add_local_item(P)



Expand Down
4 changes: 2 additions & 2 deletions code/modules/reagents/chemistry_machinery/chem_master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
P.update_icon()

if(href_list["store"])
connected.add_item(P)
connected.add_local_item(P)
else if(!Adjacent(usr) || !usr.put_in_hands(P))
P.forceMove(loc)

Expand Down Expand Up @@ -321,7 +321,7 @@
attack_hand(user)
return

connected.add_item(loaded_pill_bottle)
connected.add_local_item(loaded_pill_bottle)
loaded_pill_bottle = null

// Connecting a smartfridge
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
P.icon_state = "bottle-1" // Default bottle
beaker.reagents.trans_id_to(P, id, P.reagents.maximum_volume)
P.name = "[P.reagents.get_master_reagent_name()] bottle"
linked_storage.add_item(P)
linked_storage.add_local_item(P)
else if(href_list["dispose"])
var/id = href_list["dispose"]
beaker.reagents.del_reagent(id)
Expand Down
112 changes: 0 additions & 112 deletions nano/templates/smartfridge.tmpl

This file was deleted.

178 changes: 178 additions & 0 deletions tgui/packages/tgui/interfaces/SmartFridge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { classes } from 'common/react';
import { useBackend, useLocalState } from '../backend';
import { Button, Icon, NoticeBox, Section, Stack, Tabs } from '../components';
import { Table, TableCell, TableRow } from '../components/Table';
import { Window } from '../layouts';
import { ElectricalPanel } from './common/ElectricalPanel';

interface SmartFridgeData {
secure: number;
transfer_mode: number;
locked: number;
storage: {
contents: StorageItem[];
networked: StorageItem[];
};
networked: number;
}

interface StorageItem {
index: number;
display_name: string;
vend: number;
quantity: number;
item: string;
image: string;
category: string;
}

const ContentsTable = (
props: { isLocal: boolean; items: StorageItem[] },
context
) => {
return (
<Table className="ContentsTable">
{props.items
.sort((a, b) => a.display_name.localeCompare(b.display_name))
.map((x) => (
<TableRow key={x.display_name} className="ContentRow">
<ContentItem item={x} isLocal={props.isLocal} />
</TableRow>
))}
</Table>
);
};

const Contents = (
props: { isLocal: boolean; items: StorageItem[]; title: string },
context
) => {
const [tabIndex, setTabIndex] = useLocalState(
context,
`contentsTab_${props.isLocal}`,
'all'
);
const allItems = props.items;

if (allItems.length === 0) {
return (
<Section title={props.title}>
<span>No items present</span>
</Section>
);
}

const categories = new Map<string, StorageItem[]>();
categories.set('all', allItems);
allItems.forEach((x) => {
const categoryArray = categories.get(x.category) ?? new Array();
categoryArray.push(x);
categories.set(x.category, categoryArray);
});

const categoryIterable = Array.from(categories.entries());
return (
<Section title={props.title}>
<Tabs fill fluid>
{categoryIterable
.sort((a, b) => a[0].localeCompare(b[0]))
.map((value) => {
const key = value[0];
const items = value[1];
const displayName = `${key
.substring(0, 1)
.toUpperCase()}${key.substring(1)}`;
return (
<Tabs.Tab
key={key}
selected={tabIndex === key}
onClick={() => setTabIndex(key)}>
{displayName} ({items.length})
</Tabs.Tab>
);
})}
</Tabs>

{categoryIterable.map((x) => {
if (tabIndex !== x[0]) {
return undefined;
}
return (
<ContentsTable key={x[0]} isLocal={props.isLocal} items={x[1]} />
);
})}
</Section>
);
};

const ContentItem = (
props: { isLocal: boolean; item: StorageItem },
context
) => {
const { data, act } = useBackend<SmartFridgeData>(context);
const { item } = props;
const itemref = { 'index': item.index, 'amount': 1, isLocal: props.isLocal };
return (
<>
<TableCell className="ItemIconCell">
<span
className={classes(['ItemIcon', `vending32x32`, `${item.image}`])}
/>
</TableCell>
<TableCell className="ItemIconCell">{item.quantity}</TableCell>
<TableCell>
<Button
className="VendButton"
preserveWhitespace
textAlign="center"
icon="circle-down"
onClick={() => act('vend', itemref)}>
{item.display_name}
</Button>
</TableCell>
{data.networked === 1 && (
<TableCell>
<Button
icon={props.isLocal ? 'upload' : 'download'}
onClick={() => act('transfer', itemref)}
/>
</TableCell>
)}
<TableCell>
<Icon name="circle-info" />
</TableCell>
</>
);
};

export const SmartFridge = (_, context) => {
const { data } = useBackend<SmartFridgeData>(context);
return (
<Window theme="weyland" width={400} height={600}>
<Window.Content className="SmartFridge" scrollable>
<Stack vertical>
{data.secure && (
<Stack.Item>
<NoticeBox>Smart Fridge is in secure mode</NoticeBox>
</Stack.Item>
)}
<Stack.Item>
<Contents title="Contents" isLocal items={data.storage.contents} />
</Stack.Item>
{data.networked === 1 && (
<Stack.Item>
<Contents
title="Networked"
isLocal={false}
items={data.storage.networked}
/>
</Stack.Item>
)}
<Stack.Item>
<ElectricalPanel />
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};