mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
* Galactic Market Hot Fixes (#78836) ## About The Pull Request 1. Fixes #78732 The "Order Via Cargo Budget" button no longer appears in the UI if you don't have cargo access in your ID 2. Fixes #78730 Orders made privately & orders made via cargo budget now come in different crates  So cargo ordered crates no longer require QM cargo budget card and can be opened by anyone as intended wheras privatly ordered crates come with your regular secure access facility. This occurred when assigning the bank account to the order https://github.com/tgstation/tgstation/blob/e41730f6e455c3ece1cd52e3b67aa6c1d11cd953/code/modules/cargo/materials_market.dm#L201 This param is only meant to check if you want an access secured crate(which you should get for private orders) or an normal crate for cargo orders. If null it will send you the regular cargo crate 3. Fixes #78731 Orders made privately vs orders made with cargo budget are now separate and not bundled together  So if you first make an order privately & them switch to cargo budget or vice versa it will still separate your orders. This way you get what you ordered privately in a separate crate and cargo gets their crate separately for it's purposes 4. New Qol now money will be deducted from cargo budget/your account only after the order is confirmed in the cargo request console & after shuttle is called and arrives with your packages This way you drain the budget only after your orders were successfully delivered and not before hand itself. We don't have to worry about making orders that exceed our budget cause cargo already has bound checking code for that so let it do its thing. Here for example cargo only had 500 credits but i ordered way too much so it gracefully rejected it  6. This also addresses https://github.com/tgstation/tgstation/pull/78729#pullrequestreview-1654922282 by making the for loop treat the items in the list as paths by using the `as anything in` clause in the for loop. ## Changelog 🆑 fix: You cannot order with cargo budget if you don't have cargo access in the Galactic Market fix: Private & Cargo orders no longer get mixed together in the same crate if you order them interchangeably so no more embezzlement in the Galactic Market fix: Orders made with cargo budget come in a regular cargo crate thus allowing you to open them without QM cargo budget card in the Galactic Market qol: Orders made in the Galactic Market will deduct money from your account/cargo budget only after the order has been confirmed in the cargo request console & after the shuttle arrives with your order. This way you drain the budget only after your orders were successfully delivered and not before hand itself /🆑 * Galactic Market Hot Fixes --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
269 lines
10 KiB
Plaintext
269 lines
10 KiB
Plaintext
/obj/machinery/materials_market
|
|
name = "galactic materials market"
|
|
desc = "This machine allows the user to buy and sell sheets of minerals \
|
|
across the system. Prices are known to fluxuate quite often,\
|
|
sometimes even within the same minute. All transactions are final."
|
|
circuit = /obj/item/circuitboard/machine/materials_market
|
|
req_access = list(ACCESS_CARGO)
|
|
density = TRUE
|
|
icon = 'icons/obj/economy.dmi'
|
|
icon_state = "mat_market"
|
|
base_icon_state = "mat_market"
|
|
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION
|
|
/// What items can be converted into a stock block? Must be a stack subtype based on current implementation.
|
|
var/static/list/exportable_material_items = list(
|
|
/obj/item/stack/sheet/iron, //God why are we like this
|
|
/obj/item/stack/sheet/glass, //No really, God why are we like this
|
|
/obj/item/stack/sheet/mineral,
|
|
/obj/item/stack/tile/mineral,
|
|
/obj/item/stack/ore,
|
|
/obj/item/stack/sheet/bluespace_crystal,
|
|
/obj/item/stack/rods
|
|
)
|
|
/// Are we ordering sheets from our own card balance or the cargo budget?
|
|
var/ordering_private = TRUE
|
|
/// Currently, can we order sheets from our own card balance or the cargo budget?
|
|
var/can_buy_via_budget = FALSE
|
|
|
|
/obj/machinery/materials_market/update_icon_state()
|
|
if(panel_open)
|
|
icon_state = "[base_icon_state]_open"
|
|
return ..()
|
|
if(!is_operational || !anchored)
|
|
icon_state = "[base_icon_state]_off"
|
|
return ..()
|
|
icon_state = "[base_icon_state]"
|
|
return ..()
|
|
|
|
/obj/machinery/materials_market/wrench_act(mob/living/user, obj/item/tool)
|
|
..()
|
|
default_unfasten_wrench(user, tool, time = 1.5 SECONDS)
|
|
return TOOL_ACT_TOOLTYPE_SUCCESS
|
|
|
|
/obj/machinery/materials_market/attackby(obj/item/O, mob/user, params)
|
|
if(default_deconstruction_screwdriver(user, "[base_icon_state]_open", "[base_icon_state]", O))
|
|
return
|
|
else if(default_deconstruction_crowbar(O))
|
|
return
|
|
if(is_type_in_list(O, exportable_material_items))
|
|
var/amount = 0
|
|
var/value = 0
|
|
var/material_to_export
|
|
var/obj/item/stack/exportable = O
|
|
for(var/datum/material/mat as anything in SSstock_market.materials_prices)
|
|
if(exportable.has_material_type(mat))
|
|
amount = exportable.amount
|
|
value = SSstock_market.materials_prices[mat]
|
|
material_to_export = mat
|
|
break //This is only for trading non-alloys, so we can break here
|
|
|
|
if(!amount)
|
|
say("Not enough material. Aborting.")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE)
|
|
return TRUE
|
|
qdel(exportable)
|
|
var/obj/item/stock_block/new_block = new /obj/item/stock_block(drop_location())
|
|
new_block.export_value = amount * value * MARKET_PROFIT_MODIFIER
|
|
new_block.export_mat = material_to_export
|
|
new_block.quantity = amount
|
|
to_chat(user, span_notice("You have created a stock block worth [new_block.export_value] cr! Sell it before it becomes liquid!"))
|
|
playsound(src, 'sound/machines/synth_yes.ogg', 50, FALSE)
|
|
return TRUE
|
|
return ..()
|
|
|
|
|
|
/obj/machinery/materials_market/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!anchored)
|
|
return
|
|
if(!ui)
|
|
ui = new(user, src, "MatMarket", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/materials_market/ui_data(mob/user)
|
|
var/data = list()
|
|
var/material_data
|
|
for(var/datum/material/traded_mat as anything in SSstock_market.materials_prices)
|
|
var/trend_string = ""
|
|
if(SSstock_market.materials_trends[traded_mat] == 0)
|
|
trend_string = "neutral"
|
|
else if(SSstock_market.materials_trends[traded_mat] == 1)
|
|
trend_string = "up"
|
|
else if(SSstock_market.materials_trends[traded_mat] == -1)
|
|
trend_string = "down"
|
|
var/color_string = ""
|
|
if (initial(traded_mat.greyscale_colors))
|
|
color_string = splicetext(initial(traded_mat.greyscale_colors), 7, length(initial(traded_mat.greyscale_colors)), "") //slice it to a standard 6 char hex
|
|
else if(initial(traded_mat.color))
|
|
color_string = initial(traded_mat.color)
|
|
material_data += list(list(
|
|
"name" = initial(traded_mat.name),
|
|
"price" = SSstock_market.materials_prices[traded_mat],
|
|
"quantity" = SSstock_market.materials_quantity[traded_mat],
|
|
"trend" = trend_string,
|
|
"color" = color_string,
|
|
))
|
|
|
|
can_buy_via_budget = FALSE
|
|
var/obj/item/card/id/used_id_card
|
|
if(isliving(user))
|
|
var/mob/living/living_user = user
|
|
used_id_card = living_user.get_idcard(TRUE)
|
|
can_buy_via_budget = (ACCESS_CARGO in used_id_card?.GetAccess())
|
|
|
|
var/balance = 0
|
|
if(!ordering_private)
|
|
var/datum/bank_account/dept = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
|
if(dept)
|
|
balance = dept.account_balance
|
|
else
|
|
balance = used_id_card?.registered_account?.account_balance
|
|
|
|
var/market_crashing = FALSE
|
|
if(HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING))
|
|
market_crashing = TRUE
|
|
|
|
data["catastrophe"] = market_crashing
|
|
data["materials"] = material_data
|
|
data["creditBalance"] = balance
|
|
data["orderingPrive"] = ordering_private
|
|
data["canOrderCargo"] = can_buy_via_budget
|
|
return data
|
|
|
|
/obj/machinery/materials_market/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
//You must have an ID to be able to do something
|
|
var/mob/living/living_user = ui.user
|
|
var/obj/item/card/id/used_id_card = living_user.get_idcard(TRUE)
|
|
if(isnull(used_id_card))
|
|
say("No ID Found")
|
|
return
|
|
|
|
switch(action)
|
|
if("buy")
|
|
var/material_str = params["material"]
|
|
var/quantity = text2num(params["quantity"])
|
|
|
|
var/datum/material/material_bought
|
|
var/obj/item/stack/sheet/sheet_to_buy
|
|
for(var/datum/material/mat as anything in SSstock_market.materials_prices)
|
|
if(initial(mat.name) == material_str)
|
|
material_bought = mat
|
|
break
|
|
if(!material_bought)
|
|
CRASH("Invalid material name passed to materials market!")
|
|
|
|
//if multiple users open the UI some of them may not have the required access so we recheck
|
|
var/is_ordering_private = ordering_private
|
|
if(!(ACCESS_CARGO in used_id_card.GetAccess())) //no cargo access then force private purchase
|
|
is_ordering_private = TRUE
|
|
|
|
var/datum/bank_account/account_payable
|
|
if(is_ordering_private)
|
|
account_payable = used_id_card.registered_account
|
|
else if(can_buy_via_budget)
|
|
account_payable = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
|
if(!account_payable)
|
|
say("No bank account detected!")
|
|
return
|
|
|
|
sheet_to_buy = initial(material_bought.sheet_type)
|
|
if(!sheet_to_buy)
|
|
CRASH("Material with no sheet type being sold on materials market!")
|
|
var/cost = SSstock_market.materials_prices[material_bought] * quantity
|
|
if(cost > account_payable.account_balance)
|
|
to_chat(living_user, span_warning("You don't have enough money to buy that!"))
|
|
return
|
|
|
|
var/list/things_to_order = list()
|
|
things_to_order += (sheet_to_buy)
|
|
things_to_order[sheet_to_buy] = quantity
|
|
// We want to count how many stacks of all sheets we're ordering to make sure they don't exceed the limit of 10
|
|
// If we already have a custom order on SSshuttle, we should add the things to order to that order
|
|
for(var/datum/supply_order/order in SSshuttle.shopping_list)
|
|
// Must be a Galactic Materials Market order and payed by the null account(if ordered via cargo budget) or by correct user for private purchase
|
|
if(order.orderer_rank == "Galactic Materials Market" && ( \
|
|
(!is_ordering_private && order.paying_account == null) || \
|
|
(is_ordering_private && order.paying_account != null && order.orderer == living_user) \
|
|
))
|
|
// Check if this order exceeded its limit
|
|
var/prior_stacks = 0
|
|
for(var/obj/item/stack/sheet/sheet as anything in order.pack.contains)
|
|
prior_stacks += ROUND_UP(order.pack.contains[sheet] / 50)
|
|
if(prior_stacks >= 10)
|
|
to_chat(usr, span_notice("You already have 10 stacks of sheets on order! Please wait for them to arrive before ordering more."))
|
|
playsound(usr, 'sound/machines/synth_no.ogg', 35, FALSE)
|
|
return
|
|
// Append to this order
|
|
order.append_order(things_to_order, cost)
|
|
return
|
|
|
|
//Now we need to add a cargo order for quantity sheets of material_bought.sheet_type
|
|
var/datum/supply_pack/custom/minerals/mineral_pack = new(
|
|
purchaser = is_ordering_private ? living_user : "Cargo", \
|
|
cost = cost, \
|
|
contains = things_to_order, \
|
|
)
|
|
var/datum/supply_order/new_order = new(
|
|
pack = mineral_pack,
|
|
orderer = living_user,
|
|
orderer_rank = "Galactic Materials Market",
|
|
orderer_ckey = living_user.ckey,
|
|
paying_account = is_ordering_private ? account_payable : null,
|
|
cost_type = "credit",
|
|
can_be_cancelled = FALSE
|
|
)
|
|
say("Thank you for your purchase! It will arrive on the next cargo shuttle!")
|
|
SSshuttle.shopping_list += new_order
|
|
return
|
|
if("toggle_budget")
|
|
if(!can_buy_via_budget)
|
|
return
|
|
ordering_private = !ordering_private
|
|
|
|
/obj/item/stock_block
|
|
name = "stock block"
|
|
desc = "A block of stock. It's worth a certain amount of money, based on a sale on the materials market. Ship it on the cargo shuttle to claim your money."
|
|
icon = 'icons/obj/economy.dmi'
|
|
icon_state = "stock_block"
|
|
/// How many credits was this worth when created?
|
|
var/export_value = 0
|
|
/// What is the name of the material this was made from?
|
|
var/datum/material/export_mat
|
|
/// Quantity of export material
|
|
var/quantity = 0
|
|
/// Is this stock block currently updating it's value with the market (aka fluid)?
|
|
var/fluid = FALSE
|
|
|
|
/obj/item/stock_block/examine(mob/user)
|
|
. = ..()
|
|
. += span_notice("\The [src] is worth [export_value] cr, from selling [quantity] sheets of [initial(export_mat?.name)].")
|
|
if(fluid)
|
|
. += span_warning("\The [src] is currently liquid! It's value is based on the market price.")
|
|
else
|
|
. += span_notice("\The [src]'s value is still [span_boldnotice("locked in")]. [span_boldnotice("Sell it")] before it's value becomes liquid!")
|
|
|
|
/obj/item/stock_block/Initialize(mapload)
|
|
. = ..()
|
|
addtimer(CALLBACK(src, PROC_REF(value_warning)), 2.5 MINUTES)
|
|
addtimer(CALLBACK(src, PROC_REF(update_value)), 5 MINUTES)
|
|
|
|
/obj/item/stock_block/proc/value_warning()
|
|
visible_message(span_warning("\The [src] is starting to become liquid!"))
|
|
icon_state = "stock_block_fluid"
|
|
update_appearance(UPDATE_ICON_STATE)
|
|
|
|
/obj/item/stock_block/proc/update_value()
|
|
if(!export_mat)
|
|
return
|
|
if(!SSstock_market.materials_prices[export_mat])
|
|
return
|
|
export_value = quantity * SSstock_market.materials_prices[export_mat] * MARKET_PROFIT_MODIFIER
|
|
icon_state = "stock_block_liquid"
|
|
update_appearance(UPDATE_ICON_STATE)
|
|
visible_message(span_warning("\The [src] becomes liquid!"))
|
|
|