From 34c500e7da3713ea147cbb9b2d8e4849e4e37a99 Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+Steals-The-PRs@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:33:51 +0300 Subject: [PATCH] [MIRROR] Clamps material market quantities & prices during cargo operations (#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 <154629622+NovaBot13@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> --- code/controllers/subsystem/stock_market.dm | 31 +++++++++++++++++++++ code/modules/cargo/exports/materials.dm | 12 ++------ code/modules/cargo/packs/_packs.dm | 5 ++-- tgui/packages/tgui/interfaces/MatMarket.tsx | 6 ++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/code/controllers/subsystem/stock_market.dm b/code/controllers/subsystem/stock_market.dm index 6c4341adc8d..e486776a082 100644 --- a/code/controllers/subsystem/stock_market.dm +++ b/code/controllers/subsystem/stock_market.dm @@ -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. */ diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm index ecb0d0d0460..87817987b60 100644 --- a/code/modules/cargo/exports/materials.dm +++ b/code/modules/cargo/exports/materials.dm @@ -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. diff --git a/code/modules/cargo/packs/_packs.dm b/code/modules/cargo/packs/_packs.dm index 9257d2d1e3d..662938320cb 100644 --- a/code/modules/cargo/packs/_packs.dm +++ b/code/modules/cargo/packs/_packs.dm @@ -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) diff --git a/tgui/packages/tgui/interfaces/MatMarket.tsx b/tgui/packages/tgui/interfaces/MatMarket.tsx index 1f6d69c8d69..11de67fb656 100644 --- a/tgui/packages/tgui/interfaces/MatMarket.tsx +++ b/tgui/packages/tgui/interfaces/MatMarket.tsx @@ -55,7 +55,7 @@ export const MatMarket = (props) => { const multiplier = orderingPrive ? 1.1 : 1; return ( - + {!!catastrophe && }
{
- Current Credit Balance: {formatMoney(creditBalance)} cr. + Balance: {formatMoney(creditBalance)} cr. - Current Order Cost: {formatMoney(orderBalance)} cr. + Order: {formatMoney(orderBalance)} cr.