mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-17 02:54:44 +01:00
Stock Market UI Tweaks and improvements (#95564)
## About The Pull Request This PR pulls forward some UI tweaks that I made in #93183, but cleaned up and with some additional adjustments. This adjusts a bit of the GMM Ui, cutting out the horizontal quantity measurement and rolling that into the supply/order information in the middle. <img width="984" height="613" alt="image" src="https://github.com/user-attachments/assets/40661624-c88d-4899-a624-7f3b391edf27" /> Adds a hit of color as well to show what materials are currently being ordered. Adds a bit of tooltip text in order to showcase the range of prices that a mineral can be bought and sold at, in order to showcase why lower value minerals like glass/iron can be bought and sold from. In addition to this, also tweaks the logic on the disabling of buttons to better reflect these thresholds, so you can buy and sell when sitting on those thresholds. ## Why It's Good For The Game The market UI needs to exist in a sort of "spreadsheet" format, in order to see all the values, all the costs, and make decisions about what you what to buy and how many. That said, it's clunky, and there's a lot of complexity related to buying and selling materials already that I would love to cut down on. This helps trim the UI, makes it a bit smaller, but adds in some missing information that even I don't have memorized for the purposes of regular gameplay. ## Changelog 🆑 qol: The GMM Ui can now tell you the minimum and maximum price ranges that a material will sell for. qol: You can now sell materials on the edge of their buying and selling thresholds. (This really only effects iron and glass, practically) /🆑
This commit is contained in:
@@ -130,6 +130,7 @@
|
||||
var/sheet_to_buy
|
||||
var/requested_amount
|
||||
var/minimum_value_threshold = 0
|
||||
var/maximum_value_threshold = 0
|
||||
var/elastic_mult = 1
|
||||
for(var/datum/material/traded_mat as anything in SSstock_market.materials_prices)
|
||||
//convert trend into text
|
||||
@@ -168,6 +169,8 @@
|
||||
else
|
||||
minimum_value_threshold = round(initial(traded_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5)
|
||||
|
||||
maximum_value_threshold = round(initial(traded_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3)
|
||||
|
||||
//Pulling elastic modifier into data.
|
||||
for(var/datum/export/material/market/export_est in GLOB.exports_list)
|
||||
if(export_est.material_id == traded_mat)
|
||||
@@ -177,7 +180,8 @@
|
||||
"name" = initial(traded_mat.name),
|
||||
"price" = SSstock_market.materials_prices[traded_mat],
|
||||
"rarity" = initial(traded_mat.value_per_unit),
|
||||
"threshold" = minimum_value_threshold,
|
||||
"min_threshold" = minimum_value_threshold,
|
||||
"max_threshold" = maximum_value_threshold,
|
||||
"quantity" = SSstock_market.materials_quantity[traded_mat],
|
||||
"trend" = trend_string,
|
||||
"color" = color_string,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { sortBy } from 'es-toolkit';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Collapsible,
|
||||
Modal,
|
||||
NoticeBox,
|
||||
Section,
|
||||
Stack,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
import { formatMoney } from 'tgui-core/format';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
@@ -20,7 +22,8 @@ type Material = {
|
||||
rarity: number;
|
||||
trend: string;
|
||||
price: number;
|
||||
threshold: number;
|
||||
min_threshold: number;
|
||||
max_threshold: number;
|
||||
color: string;
|
||||
requested: number;
|
||||
elastic: number;
|
||||
@@ -56,17 +59,18 @@ export const MatMarket = (props) => {
|
||||
const multiplier = orderingPrive ? 1.1 : 1;
|
||||
|
||||
return (
|
||||
<Window width={1110} height={600}>
|
||||
<Window width={990} height={615}>
|
||||
<Window.Content scrollable>
|
||||
{!!catastrophe && <MarketCrashModal />}
|
||||
<Section
|
||||
title="Materials for sale"
|
||||
buttons={
|
||||
!!canOrderCargo && (
|
||||
<Button
|
||||
icon="dollar"
|
||||
<Button.Checkbox
|
||||
icon={orderingPrive ? "fa-regular fa-square" : "square-check"}
|
||||
tooltip="Place order from cargo budget."
|
||||
color={orderingPrive ? '' : 'green'}
|
||||
color={orderingPrive ? 'transparent' : 'green'}
|
||||
checked={orderingPrive}
|
||||
content={
|
||||
orderingPrive
|
||||
? 'Order via Cargo Budget?'
|
||||
@@ -77,24 +81,6 @@ export const MatMarket = (props) => {
|
||||
)
|
||||
}
|
||||
>
|
||||
<NoticeBox info>
|
||||
<Collapsible title="Instructions" color="blue">
|
||||
Buy orders for material sheets placed here will be ordered on the
|
||||
next cargo shipment.
|
||||
<br /> <br />
|
||||
To sell materials, please insert sheets or similar stacks of
|
||||
materials. All minerals sold on the market directly are subject to
|
||||
a scaling value decrease per material, but this will recover over
|
||||
time. To prevent market manipulation, all registered traders can
|
||||
buy a total of 10 full stacks of materials at a time.
|
||||
<br /> <br />
|
||||
When selling materials, prices will be decreased based on the
|
||||
elastic modifier of the material, which will recover over time.
|
||||
<br /> <br />
|
||||
All new purchases will include the cost of the shipped crate,
|
||||
which may be recycled afterwards.
|
||||
</Collapsible>
|
||||
</NoticeBox>
|
||||
<Section>
|
||||
<Stack>
|
||||
<Stack.Item width="15%">
|
||||
@@ -127,7 +113,7 @@ export const MatMarket = (props) => {
|
||||
(material, i) => (
|
||||
<Section key={i}>
|
||||
<Stack fill>
|
||||
<Stack.Item width="75%">
|
||||
<Stack.Item width="82%">
|
||||
<Stack>
|
||||
<Stack.Item
|
||||
textColor={material.color ? material.color : 'white'}
|
||||
@@ -151,24 +137,39 @@ export const MatMarket = (props) => {
|
||||
Elasticity: <b>{Math.round(material.elastic)}</b>%
|
||||
</Stack.Item>
|
||||
|
||||
<Stack.Item width="15%" pr="2%">
|
||||
Trading at <b>{formatMoney(material.price)}</b> cr.
|
||||
<Stack.Item
|
||||
width="15%"
|
||||
pr="2%"
|
||||
>
|
||||
<Tooltip
|
||||
content={rangeText({ minPrice: material.min_threshold, maxPrice: material.max_threshold })}
|
||||
>
|
||||
<u>Trading at <br /><b>{formatMoney(material.price)}</b> cr.</u>
|
||||
</Tooltip>
|
||||
|
||||
</Stack.Item>
|
||||
{material.price < material.threshold ? (
|
||||
{material.price < material.min_threshold ? (
|
||||
<Stack.Item width="33%" ml={2} textColor="grey">
|
||||
Material price critical!
|
||||
<br /> <b>Trading temporarily suspended.</b>
|
||||
</Stack.Item>
|
||||
) : (
|
||||
<Stack.Item width="33%" ml={2}>
|
||||
<b>{material.quantity || 'Zero'}</b> sheets of{' '}
|
||||
<b>{material.name}</b> trading.{' '}
|
||||
{material.requested || 'Zero'} sheets ordered.
|
||||
<Box textColor={material.quantity === 0 ? 'grey' : 'white'}>
|
||||
<b>{material.quantity || 'Zero'}</b> sheets of{' '}
|
||||
<b>{material.name}</b> trading.{' '}
|
||||
</Box>
|
||||
<Box
|
||||
bold={!!material.requested}
|
||||
textColor={material.requested > 0 ? 'lightblue' : 'white'}
|
||||
>
|
||||
{material.requested || 'Zero'} sheets ordered.
|
||||
</Box>
|
||||
</Stack.Item>
|
||||
)}
|
||||
|
||||
<Stack.Item
|
||||
width="40%"
|
||||
width="20%"
|
||||
color={
|
||||
material.trend === 'up'
|
||||
? 'green'
|
||||
@@ -184,9 +185,11 @@ export const MatMarket = (props) => {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
height="35px"
|
||||
verticalAlignContent="middle"
|
||||
disabled={
|
||||
catastrophe === 1 ||
|
||||
material.price <= material.threshold ||
|
||||
material.price < material.min_threshold ||
|
||||
creditBalance - total_order_cost <
|
||||
material.price * multiplier ||
|
||||
material.requested + 1 > material.quantity
|
||||
@@ -202,9 +205,11 @@ export const MatMarket = (props) => {
|
||||
Buy 1
|
||||
</Button>
|
||||
<Button
|
||||
height="35px"
|
||||
verticalAlignContent="middle"
|
||||
disabled={
|
||||
catastrophe === 1 ||
|
||||
material.price <= material.threshold ||
|
||||
material.price < material.min_threshold ||
|
||||
creditBalance - total_order_cost <
|
||||
material.price * 5 * multiplier ||
|
||||
material.requested + 5 > material.quantity
|
||||
@@ -220,9 +225,11 @@ export const MatMarket = (props) => {
|
||||
5
|
||||
</Button>
|
||||
<Button
|
||||
height="35px"
|
||||
verticalAlignContent="middle"
|
||||
disabled={
|
||||
catastrophe === 1 ||
|
||||
material.price <= material.threshold ||
|
||||
material.price < material.min_threshold ||
|
||||
creditBalance - total_order_cost <
|
||||
material.price * 10 * multiplier ||
|
||||
material.requested + 10 > material.quantity
|
||||
@@ -238,9 +245,11 @@ export const MatMarket = (props) => {
|
||||
10
|
||||
</Button>
|
||||
<Button
|
||||
height="35px"
|
||||
verticalAlignContent="middle"
|
||||
disabled={
|
||||
catastrophe === 1 ||
|
||||
material.price <= material.threshold ||
|
||||
material.price < material.min_threshold ||
|
||||
creditBalance - total_order_cost <
|
||||
material.price * 25 * multiplier ||
|
||||
material.requested + 25 > material.quantity
|
||||
@@ -256,9 +265,11 @@ export const MatMarket = (props) => {
|
||||
25
|
||||
</Button>
|
||||
<Button
|
||||
height="35px"
|
||||
verticalAlignContent="middle"
|
||||
disabled={
|
||||
catastrophe === 1 ||
|
||||
material.price <= material.threshold ||
|
||||
material.price < material.min_threshold ||
|
||||
creditBalance - total_order_cost <
|
||||
material.price * 50 * multiplier ||
|
||||
material.requested + 50 > material.quantity
|
||||
@@ -274,13 +285,28 @@ export const MatMarket = (props) => {
|
||||
50
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
{material.requested > 0 && (
|
||||
<Stack.Item ml={2}>x {material.requested}</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
</Section>
|
||||
),
|
||||
)}
|
||||
<NoticeBox info>
|
||||
<Collapsible title="Instructions" color="blue">
|
||||
Buy orders for material sheets placed here will be ordered on the
|
||||
next cargo shipment.
|
||||
<br /> <br />
|
||||
To sell materials, please insert sheets or similar stacks of
|
||||
materials. All minerals sold on the market directly are subject to
|
||||
a scaling value decrease per material, but this will recover over
|
||||
time. To prevent market manipulation, all registered traders can
|
||||
buy a total of 10 full stacks of materials at a time.
|
||||
<br /> <br />
|
||||
When selling materials, prices will be decreased based on the
|
||||
elastic modifier of the material, which will recover over time.
|
||||
<br /> <br />
|
||||
All new purchases will include the cost of the shipped crate,
|
||||
which may be recycled afterwards.
|
||||
</Collapsible>
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
@@ -299,3 +325,16 @@ const MarketCrashModal = (props) => {
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
type rangeTextProps = {
|
||||
minPrice: number;
|
||||
maxPrice: number;
|
||||
}
|
||||
|
||||
function rangeText(props: rangeTextProps) {
|
||||
const {minPrice, maxPrice} = props;
|
||||
return (
|
||||
"This material can be bought and sold between " + formatMoney(minPrice) +
|
||||
" - " + formatMoney(maxPrice) + " cr."
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user