diff --git a/code/__DEFINES/uplink.dm b/code/__DEFINES/uplink.dm index cdfdf4680f7..929b558dfec 100644 --- a/code/__DEFINES/uplink.dm +++ b/code/__DEFINES/uplink.dm @@ -36,7 +36,7 @@ /// Typepath used for uplink items which don't actually produce an item (essentially just a placeholder) /// Future todo: Make this not necessary / make uplink items support item-less items natively -#define ABSTRACT_UPLINK_ITEM /obj/effect/gibspawner/generic +#define ABSTRACT_UPLINK_ITEM /obj/item/loot_table_maker /// Lower threshold for which an uplink items's TC cost is considered "low" for spy bounties picking rewards #define SPY_LOWER_COST_THRESHOLD 5 diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index a5ff46964bf..d831ba2f0d9 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -227,9 +227,12 @@ for(var/datum/uplink_item/item as anything in uplink_handler.extra_purchasable) if(item.stock_key in stock_list) extra_purchasable_stock[REF(item)] = stock_list[item.stock_key] + var/atom/actual_item = item.item extra_purchasable += list(list( "id" = item.type, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, @@ -288,6 +291,11 @@ return item = SStraitor.uplink_items_by_type[item_path] uplink_handler.purchase_item(ui.user, item, parent) + if("buy_raw_tc") + if (uplink_handler.telecrystals <= 0) + return + var/desired_amount = tgui_input_number(ui.user, "How many raw telecrystals to buy?", "Buy Raw TC", default = uplink_handler.telecrystals, max_value = uplink_handler.telecrystals) + uplink_handler.purchase_raw_tc(ui.user, desired_amount, parent) if("lock") if(!lockable) return TRUE diff --git a/code/modules/antagonists/traitor/uplink_handler.dm b/code/modules/antagonists/traitor/uplink_handler.dm index f78ddb02478..2d27f3c4a0e 100644 --- a/code/modules/antagonists/traitor/uplink_handler.dm +++ b/code/modules/antagonists/traitor/uplink_handler.dm @@ -126,6 +126,21 @@ on_update() return TRUE +/datum/uplink_handler/proc/purchase_raw_tc(mob/user, amount, atom/movable/source) + if(shop_locked) + return FALSE + if(telecrystals < amount) + return FALSE + + telecrystals -= amount + var/tcs = new /obj/item/stack/telecrystal(get_turf(user), amount) + user.put_in_hands(tcs) + + log_uplink("[key_name(user)] purchased [amount] raw telecrystals from [source]'s uplink") + on_update() + return TRUE + + /// Generates objectives for this uplink handler /datum/uplink_handler/proc/generate_objectives() var/potential_objectives_left = maximum_potential_objectives - (length(potential_objectives) + length(active_objectives)) diff --git a/code/modules/asset_cache/assets/uplink.dm b/code/modules/asset_cache/assets/uplink.dm index e85ee1b35b5..35a907a234d 100644 --- a/code/modules/asset_cache/assets/uplink.dm +++ b/code/modules/asset_cache/assets/uplink.dm @@ -18,10 +18,13 @@ for(var/datum/uplink_item/item_path as anything in subtypesof(/datum/uplink_item)) var/datum/uplink_item/item = new item_path() + var/atom/actual_item = item.item if(item.item) { items += list(list( "id" = item_path, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, diff --git a/code/modules/uplink/uplink_items/bundle.dm b/code/modules/uplink/uplink_items/bundle.dm index dae6166d49c..b6cdc2fd3d6 100644 --- a/code/modules/uplink/uplink_items/bundle.dm +++ b/code/modules/uplink/uplink_items/bundle.dm @@ -40,18 +40,7 @@ // Don't add telecrystals to the purchase_log since // it's just used to buy more items (including itself!) purchase_log_vis = FALSE - -/datum/uplink_item/bundles_tc/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/bundles_tc/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 + purchasable_from = NONE /datum/uplink_item/bundles_tc/bundle_a name = "Syndi-kit Tactical" diff --git a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx index 7b799e96552..88520752b1e 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx @@ -188,6 +188,8 @@ export const AntagInfoMalf = (props) => { items.push({ id: item.name, name: item.name, + icon: item.icon, + icon_state: item.icon_state, category: category.name, cost: `${item.cost} PT`, desc: item.desc, diff --git a/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx b/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx index 6f69b6671eb..c6558321b69 100644 --- a/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx @@ -1,9 +1,13 @@ import { BooleanLike } from 'common/react'; import { useState } from 'react'; +import { Tooltip } from 'tgui-core/components'; +import { useBackend } from '../../backend'; import { Box, Button, + DmIcon, + Icon, Input, NoticeBox, Section, @@ -19,6 +23,7 @@ type GenericUplinkProps = { }; export const GenericUplink = (props: GenericUplinkProps) => { + const { act } = useBackend(); const { currency = 'cr', categories, @@ -36,43 +41,71 @@ export const GenericUplink = (props: GenericUplinkProps) => { }); return ( -
{currency}} - buttons={ - <> - Search - setSearchText(value)} - mx={1} - /> - - - } - > - - {searchText.length === 0 && ( - - + + + + + + + + + +
+ + + ); }; export type Item = { id: string | number; name: string; + icon: string; + icon_state: string; category: string; cost: JSX.Element | string; desc: JSX.Element | string; @@ -109,22 +144,86 @@ export type ItemListProps = { const ItemList = (props: ItemListProps) => { const { compactMode, items, handleBuy } = props; + const fallback = ( + + ); return ( - + {items.map((item, index) => ( - -
handleBuy(item)} - /> - } - > - {compactMode ? null : item.desc} + +
+ + + + + + + + {compactMode ? ( + + + {item.name} + + + + + + + + + + + ) : ( +
handleBuy(item)} + > + {item.cost} + + } + > + + {item.desc} + +
+ )} +
+
))} diff --git a/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx b/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx index ee6e81160d3..f0364e88d9f 100644 --- a/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx @@ -12,19 +12,17 @@ export const PrimaryObjectiveMenu = (props: PrimaryObjectiveMenuProps) => { const { act } = useBackend(); const { primary_objectives, final_objective, can_renegotiate } = props; return ( -
-
- - { - 'Agent, your Primary Objectives are as follows. Complete these at all costs.' - } - - - { - 'Completing Secondary Objectives may allow you to aquire additional equipment.' - } - -
+
+ + WELCOME, AGENT. + + + Your Primary Objectives are as follows. Complete these at all costs. + + + Completing Secondary Objectives may allow you to aquire additional + equipment. + {final_objective && ( { )} -
- - {primary_objectives.map((prim_obj, index) => ( - - - - ))} - -
+ + {primary_objectives.map((prim_obj, index) => ( + + + + ))} + {!!can_renegotiate && (
); }; diff --git a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx index e8951e367a9..d67dd37391e 100644 --- a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx @@ -90,7 +90,7 @@ export const dangerLevelsTooltip = ( color="white" className={value.gradient} style={{ - borderRadius: '5px', + borderRadius: '2px', display: 'inline-block', }} px={0.8} @@ -137,11 +137,12 @@ export const calculateDangerLevel = ( color="white" className={dangerLevel.gradient} style={{ - borderRadius: '5px', + borderRadius: '2px', display: 'inline-block', }} px={0.8} py={0.6} + textAlign="center" > {dangerLevel.title} ({displayedProgression}) diff --git a/tgui/packages/tgui/interfaces/Uplink/index.tsx b/tgui/packages/tgui/interfaces/Uplink/index.tsx index 4949fc94ee7..3ed7d34a214 100644 --- a/tgui/packages/tgui/interfaces/Uplink/index.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/index.tsx @@ -7,6 +7,7 @@ import { Box, Button, Dimmer, + NoticeBox, Section, Stack, Tabs, @@ -27,6 +28,8 @@ import { PrimaryObjectiveMenu } from './PrimaryObjectiveMenu'; type UplinkItem = { id: string; name: string; + icon: string; + icon_state: string; cost: number; desc: string; category: string; @@ -90,6 +93,8 @@ type ServerData = { type ItemExtraData = Item & { extraData: { ref?: string; + icon: string; + icon_state: string; }; }; @@ -198,7 +203,6 @@ export class Uplink extends Component<{}, UplinkState> { shop_locked, } = data; const { allItems, allCategories, currentTab } = this.state as UplinkState; - const itemsToAdd = [...allItems]; const items: ItemExtraData[] = []; itemsToAdd.push(...extra_purchasable); @@ -224,19 +228,21 @@ export class Uplink extends Component<{}, UplinkState> { items.push({ id: item.id, name: item.name, + icon: item.icon, + icon_state: item.icon_state, category: item.category, desc: ( - - {item.desc} + <> + {item.desc} {(item.lock_other_purchases && ( - + Taking this item will lock you from further purchasing from the marketplace. Additionally, if you have already purchased an item, you will not be able to purchase this. - + )) || null} - + ), cost: ( @@ -259,6 +265,8 @@ export class Uplink extends Component<{}, UplinkState> { (item.lock_other_purchases && purchased_items > 0), extraData: { ref: item.ref, + icon: item.icon, + icon_state: item.icon_state, }, }); } @@ -274,25 +282,14 @@ export class Uplink extends Component<{}, UplinkState> { // Round it and convert it into a percentage progressionPercentage = Math.round(progressionPercentage * 1000) / 10; return ( - - - - -
- - - - SyndOS Version 3.17   - - Connection Secure - - - - WELCOME, AGENT. - - - - + + + + {!!has_progression && ( + +
+ + { } > {/* If we have no progression, - just give them a generic title */} + just give them a generic title */} {has_progression ? calculateDangerLevel(progression_points, false) : calculateDangerLevel(dangerDefault, false)} - - - {telecrystals} TC - - - -
-
- -
- - - - {!!has_objectives && ( - <> - this.setState({ currentTab: 0 })} - > - Primary Objectives - - this.setState({ currentTab: 1 })} - > - Secondary Objectives - - - )} - this.setState({ currentTab: 2 })} - > - Market - - - - {!!lockable && ( - -
-
+ + + + {!!has_objectives && ( + <> + this.setState({ currentTab: 0 })} + > + Primary Objectives + + this.setState({ currentTab: 1 })} + > + Secondary Objectives + + + )} + this.setState({ currentTab: 2 })} + > + Market + + + + + {!!lockable && ( + + + + )} +
+
+
+ )} {(currentTab === 0 && has_objectives && ( { handleRequestObjectives={() => act('regenerate_objectives')} /> )) || ( -
+ <> { @@ -471,7 +483,7 @@ export class Uplink extends Component<{}, UplinkState> { )) || null} -
+ )}