Skip to content

Commit

Permalink
[MIRROR] Clamps material market quantities & prices during cargo oper…
Browse files Browse the repository at this point in the history
…ations (#1769) (#2706)

* Clamps material market quantities & prices during cargo operations (#82338)

## About The Pull Request
- Fixes #82329

Cargo operations means buying & selling materials on the market. Now
both their prices & quantities are clamped during these operations

Also increased the width of materials market UI so large numbers don't
overflow to the next line.

## Changelog
:cl:
fix: buying & selling huge quantities of materials on the market won't
cause their prices & quantities to go beyond bounds.
/:cl:

* Clamps material market quantities & prices during cargo operations

---------

Co-authored-by: NovaBot <[email protected]>
Co-authored-by: SyncIt21 <[email protected]>
  • Loading branch information
3 people authored Apr 3, 2024
1 parent 80740cb commit 34c500e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
31 changes: 31 additions & 0 deletions code/controllers/subsystem/stock_market.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,37 @@ SUBSYSTEM_DEF(stock_market)
for(var/datum/stock_market_event/event as anything in active_events)
event.handle()

///Adjust the price of a material(either through buying or selling) ensuring it stays within limits
/datum/controller/subsystem/stock_market/proc/adjust_material_price(datum/material/mat, delta)
mat = GET_MATERIAL_REF(mat)

//adjust the price
var/new_price = materials_prices[mat.type] + delta

//get the limits
var/price_minimum = round(mat.value_per_unit * SHEET_MATERIAL_AMOUNT * 0.5)
if(!isnull(mat.minimum_value_override))
price_minimum = round(mat.minimum_value_override * SHEET_MATERIAL_AMOUNT)
var/price_maximum = round(mat.value_per_unit * SHEET_MATERIAL_AMOUNT * 3)

//clamp it down
new_price = round(clamp(new_price, price_minimum, price_maximum))
materials_prices[mat.type] = new_price

///Adjust the amount of material(either through buying or selling) ensuring it stays within limits
/datum/controller/subsystem/stock_market/proc/adjust_material_quantity(datum/material/mat, delta)
mat = GET_MATERIAL_REF(mat)

//adjust the quantity
var/new_quantity = materials_quantity[mat.type] + delta

//get the upper limit
var/quantity_baseline = mat.tradable_base_quantity

//clamp it down
new_quantity = round(clamp(new_quantity, 0, quantity_baseline * 2))
materials_quantity[mat.type] = new_quantity

/**
* Handles shifts in the cost of materials, and in what direction the material is most likely to move.
*/
Expand Down
12 changes: 2 additions & 10 deletions code/modules/cargo/exports/materials.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,11 @@

//This formula should impact lower quantity materials greater, and higher quantity materials less. Still, it's a bit rough. Tweaking may be needed.
if(!dry_run)
//this material is worthless. no point adding more to the stock
var/market_price = SSstock_market.materials_prices[material_id]
if(!market_price)
return

//decrease the market price
market_price -= round((market_price) * (amount / (amount + SSstock_market.materials_quantity[material_id])))
if(market_price < 0)
market_price = 0
SSstock_market.materials_prices[material_id] = market_price
SSstock_market.adjust_material_price(material_id, -SSstock_market.materials_prices[material_id] * (amount / (amount + SSstock_market.materials_quantity[material_id])))

//increase the stock
SSstock_market.materials_quantity[material_id] += amount
SSstock_market.adjust_material_quantity(material_id, amount)


// Stock blocks are a special type of export that can be used to sell a quantity of materials at a specific price on the market.
Expand Down
5 changes: 3 additions & 2 deletions code/modules/cargo/packs/_packs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
var/fraction = available_quantity
if(market_quantity != available_quantity) //to avoid division by zero error
fraction /= (market_quantity - available_quantity)
SSstock_market.materials_prices[material_type] += round(SSstock_market.materials_prices[material_type] * fraction)
SSstock_market.adjust_material_price(material_type, SSstock_market.materials_prices[material_type] * fraction)

//We decrease the quantity only after adjusting our prices for accurate values
SSstock_market.materials_quantity[material_type] -= available_quantity
SSstock_market.adjust_material_quantity(material_type, -available_quantity)
6 changes: 3 additions & 3 deletions tgui/packages/tgui/interfaces/MatMarket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const MatMarket = (props) => {
const multiplier = orderingPrive ? 1.1 : 1;

return (
<Window width={880} height={690}>
<Window width={1110} height={600}>
<Window.Content scrollable>
{!!catastrophe && <MarketCrashModal />}
<Section
Expand Down Expand Up @@ -93,10 +93,10 @@ export const MatMarket = (props) => {
<Section>
<Stack>
<Stack.Item width="15%">
Current Credit Balance: <b>{formatMoney(creditBalance)}</b> cr.
Balance: <b>{formatMoney(creditBalance)}</b> cr.
</Stack.Item>
<Stack.Item width="15%">
Current Order Cost: <b>{formatMoney(orderBalance)}</b> cr.
Order: <b>{formatMoney(orderBalance)}</b> cr.
</Stack.Item>
<Stack.Item
width="20%"
Expand Down

0 comments on commit 34c500e

Please sign in to comment.