mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-03-07 11:04:36 +01:00
CORPORATION: Update tooltip of storage space (#1237)
The tooltip of the storage space only shows sizes of materials/products. This is confusing for newbies. They use "Unit" (number of material/product units) when buying materials, but that tooltip only shows sizes without any description.
This commit is contained in:
@ -11,7 +11,7 @@ import { ProductElem } from "./ProductElem";
|
||||
import { MaterialElem } from "./MaterialElem";
|
||||
import { MaterialInfo } from "../MaterialInfo";
|
||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||
import { formatBigNumber, formatMaterialSize } from "../../ui/formatNumber";
|
||||
import { formatBigNumber, formatMaterialSize, formatNumber } from "../../ui/formatNumber";
|
||||
|
||||
import { Corporation } from "../Corporation";
|
||||
import { Division } from "../Division";
|
||||
@ -100,24 +100,36 @@ function WarehouseRoot(props: WarehouseProps): React.ReactElement {
|
||||
for (const matName of corpConstants.materialNames) {
|
||||
const mat = props.warehouse.materials[matName];
|
||||
if (mat.stored === 0) continue;
|
||||
breakdownItems.push([`${matName}:`, `${formatMaterialSize(mat.stored * MaterialInfo[matName].size)}`]);
|
||||
breakdownItems.push([
|
||||
`${matName}:`,
|
||||
`${formatMaterialSize(MaterialInfo[matName].size)}`,
|
||||
`${formatNumber(mat.stored)}`,
|
||||
`${formatMaterialSize(mat.stored * MaterialInfo[matName].size)}`,
|
||||
]);
|
||||
}
|
||||
|
||||
for (const [prodName, product] of division.products) {
|
||||
breakdownItems.push([
|
||||
`${prodName}:`,
|
||||
`${formatMaterialSize(product.size)}`,
|
||||
`${formatNumber(product.cityData[props.currentCity].stored)}`,
|
||||
`${formatMaterialSize(product.cityData[props.currentCity].stored * product.size)}`,
|
||||
]);
|
||||
}
|
||||
|
||||
const breakdown = breakdownItems.length > 0 ? <StatsTable rows={breakdownItems} /> : <>No items in storage.</>;
|
||||
if (breakdownItems.length > 0) {
|
||||
breakdownItems.unshift(["", "Size", "Units", "Total Space"]);
|
||||
}
|
||||
|
||||
const breakdown =
|
||||
breakdownItems.length > 0 ? <StatsTable rows={breakdownItems} paddingLeft="1em" /> : <>No items in storage.</>;
|
||||
|
||||
return (
|
||||
<Paper>
|
||||
<Box display="flex" alignItems="center">
|
||||
<Tooltip title={breakdown}>
|
||||
<Typography color={props.warehouse.sizeUsed >= props.warehouse.size ? "error" : "primary"}>
|
||||
Storage: {formatBigNumber(props.warehouse.sizeUsed)} / {formatBigNumber(props.warehouse.size)}
|
||||
Storage space: {formatBigNumber(props.warehouse.sizeUsed)} / {formatBigNumber(props.warehouse.size)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
@ -29,7 +29,7 @@ You should look around to get familiar with the UI. One confusing thing for newb
|
||||
|
||||
If you want to buy something, write a script to do that. It's too error-prone to do it manually.
|
||||
|
||||
When you hover your mouse over a warehouse, you'll see the space that those materials take up in the warehouse. They are _not_ the numbers of units.
|
||||
When you hover your mouse over "Storage space", you'll see the space that materials/products take up and the number of units in the warehouse.
|
||||
|
||||
## Terms
|
||||
|
||||
|
@ -29,7 +29,7 @@ $$ExpectedSalesVolume = \frac{ProducedUnits}{10}$$
|
||||
|
||||
- This means we want to sell all produced units.
|
||||
|
||||
In cycle's SALE state, game calculates `MaxSalesVolume` of material/product. If we set price too high, `MaxSalesVolume` is penalized. In order to maximize profit, we have to set the highest possible price while `MaxSalesVolume` is still equals to `ExpectedSalesVolume`. This is what Market-TA2 does.
|
||||
In cycle's SALE state, game calculates `MaxSalesVolume` of material/product. If we set price too high, `MaxSalesVolume` is penalized. In order to maximize profit, we have to set the highest possible price while `MaxSalesVolume` is still equal to `ExpectedSalesVolume`. This is what Market-TA2 does.
|
||||
|
||||
Calculation of material and product is pretty similar, so I'll call them "item" and use 1 formula.
|
||||
|
||||
@ -72,7 +72,7 @@ $$MarkupMultiplier = \begin{cases}\frac{MarketPrice}{SellingPrice}, & SellingPri
|
||||
|
||||
## Optimal selling price
|
||||
|
||||
As we can see with previous part, `MarkupMultiplier` is basically a penalty modifier if we set `SellingPrice` greater than `(MarketPrice + MarkupLimit)`, and we'll always do this. This means we need to find out highest possible `SellingPrice` while `MaxSalesVolume` is still equals to `ExpectedSalesVolume`.
|
||||
As we can see with previous part, `MarkupMultiplier` is basically a penalty modifier if we set `SellingPrice` greater than `(MarketPrice + MarkupLimit)`, and we'll always do this. This means we need to find out highest possible `SellingPrice` while `MaxSalesVolume` is still equal to `ExpectedSalesVolume`.
|
||||
|
||||
This is the reason why we should not bother with Market-TA1. It simply sets `SellingPrice = MarketPrice + MarkupLimit`. This means Market-TA1 sets a "safe" `SellingPrice` for us, it guarantees that we won't be penalized due to too high price. However, this "safe" `SellingPrice` is too low, and we can find a much higher `SellingPrice`.
|
||||
|
||||
@ -82,7 +82,7 @@ Formula:
|
||||
|
||||
$$M = \ ItemMultiplier\ast BusinessFactor\ast AdvertFactor\ast MarketFactor\ast SaleBotsBonus\ast ResearchBonus$$
|
||||
|
||||
- We want `MaxSalesVolume` equals `ExpectedSalesVolume`:
|
||||
- We want `MaxSalesVolume` to equal `ExpectedSalesVolume`:
|
||||
|
||||
$$MaxSalesVolume = ExpectedSalesVolume$$
|
||||
|
||||
|
@ -8,16 +8,18 @@ interface StatsTableProps {
|
||||
rows: ReactNode[][];
|
||||
title?: string;
|
||||
wide?: boolean;
|
||||
paddingLeft?: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
firstCell: { textAlign: "left" },
|
||||
nonFirstCell: { textAlign: "right", paddingLeft: "0.5em" },
|
||||
});
|
||||
const useStyles = (paddingLeft: string) =>
|
||||
makeStyles({
|
||||
firstCell: { textAlign: "left" },
|
||||
nonFirstCell: { textAlign: "right", paddingLeft: paddingLeft },
|
||||
})();
|
||||
|
||||
export function StatsTable({ rows, title, wide }: StatsTableProps): ReactElement {
|
||||
export function StatsTable({ rows, title, wide, paddingLeft }: StatsTableProps): ReactElement {
|
||||
const T = wide ? MuiTable : Table;
|
||||
const classes = useStyles();
|
||||
const classes = useStyles(paddingLeft ?? "0.5em");
|
||||
return (
|
||||
<>
|
||||
{title && <Typography>{title}</Typography>}
|
||||
|
@ -179,8 +179,8 @@ export const formatRespect = (n: number) => formatNumber(n, 5);
|
||||
export const formatWanted = formatRespect;
|
||||
export const formatPreciseMultiplier = formatRespect;
|
||||
|
||||
/** Format a number with no suffix and 1 fractional digit. */
|
||||
export const formatMaterialSize = (n: number) => formatNumberNoSuffix(n, 1);
|
||||
/** Format a number with 3 fractional digits. */
|
||||
export const formatMaterialSize = (n: number) => formatNumber(n, 3);
|
||||
|
||||
/** Format a number with no suffix and 2 fractional digits. */
|
||||
export const formatMultiplier = (n: number) => formatNumberNoSuffix(n, 2);
|
||||
|
Reference in New Issue
Block a user