[MIRROR] Clamps material market quantities & prices during cargo operations (#27146)

* 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
🆑
fix: buying & selling huge quantities of materials on the market won't
cause their prices & quantities to go beyond bounds.
/🆑

* Clamps material market quantities & prices during cargo operations

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-04-04 21:52:20 +02:00
committed by GitHub
co-authored by SyncIt21
parent 788adf8780
commit ea9544d8a7
4 changed files with 39 additions and 15 deletions
@@ -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.
*/
+2 -10
View File
@@ -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.
+3 -2
View File
@@ -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)
+3 -3
View File
@@ -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
@@ -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%"