mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 16:14:08 +01:00
6c5fa75ecd
## About The Pull Request Re-enables purchase of the GMM, however the GMM can only be used to purchase materials not sell them. ## Why It's Good For The Game Let the station buy materials if they're desperate/lowpop. If people were selling insane amounts of material inflating the budget, just remove the ability to sell. Don't remove the entire machine. ## Changelog 🆑 LT3 add: Galactic materials market can be used by cargo for purchasing materials only /🆑
396 lines
14 KiB
Plaintext
396 lines
14 KiB
Plaintext
/// The maximum number of stacks you can place in 1 order
|
|
#define MAX_STACK_LIMIT 10
|
|
/// The order rank for all galactic material market orders
|
|
#define GALATIC_MATERIAL_ORDER "Galactic Materials Market"
|
|
|
|
/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
|
|
light_power = 3
|
|
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
|
/// Are we ordering sheets from our own card balance or the cargo budget?
|
|
var/ordering_private = TRUE
|
|
|
|
/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)
|
|
. = ..()
|
|
if(default_unfasten_wrench(user, tool, time = 1.5 SECONDS) == SUCCESSFUL_UNFASTEN)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/materials_market/screwdriver_act(mob/living/user, obj/item/tool)
|
|
. = ..()
|
|
if(default_deconstruction_screwdriver(user, "[base_icon_state]_open", "[base_icon_state]", tool))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/materials_market/crowbar_act(mob/living/user, obj/item/tool)
|
|
. = ..()
|
|
if(default_deconstruction_crowbar(tool))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/materials_market/item_interaction(mob/living/user, obj/item/stack/exportable, list/modifiers)
|
|
. = NONE
|
|
if(!isstack(exportable))
|
|
return
|
|
|
|
// BUBBER EDIT ADDITION BEGIN - GMM can't sell materials
|
|
balloon_alert(user, "export not available!")
|
|
return ITEM_INTERACT_FAILURE
|
|
// BUBBER EDIT ADDITION END - GMM can't sell materials
|
|
|
|
// BUBBER EDIT REMOVAL BEGIN - GMM can't sell materials
|
|
/*
|
|
if(!is_operational)
|
|
balloon_alert(user, "no power!")
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
var/list/datum/material/materials = exportable.custom_materials
|
|
if(materials.len != 1)
|
|
balloon_alert(user, "alloy stacks not allowed")
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
var/price = SSstock_market.materials_prices[materials[1].type]
|
|
if(!price)
|
|
balloon_alert(user, "materials in stack are worthless")
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
if(!user.transferItemToLoc(exportable, src))
|
|
to_chat(user, span_warning("[exportable] is stuck in hand!"))
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
var/obj/item/stock_block/new_block = new /obj/item/stock_block(drop_location())
|
|
new_block.export_value = price
|
|
new_block.set_custom_materials(materials)
|
|
to_chat(user, span_notice("You have created a stock block worth [new_block.export_value * exportable.amount] [MONEY_SYMBOL]! Sell it before it becomes liquid!"))
|
|
playsound(src, 'sound/machines/synth/synth_yes.ogg', 50, FALSE)
|
|
qdel(exportable)
|
|
use_energy(active_power_usage)
|
|
return ITEM_INTERACT_SUCCESS
|
|
*/
|
|
// BUBBER EDIT REMOVAL END - GMM can't sell materials
|
|
|
|
/obj/machinery/materials_market/power_change()
|
|
. = ..()
|
|
if(!is_operational)
|
|
set_light(0, 0)
|
|
else
|
|
set_light(initial(light_range), initial(light_power))
|
|
|
|
/**
|
|
* Find the order purchased either privately or by cargo budget
|
|
* Arguments
|
|
* * [user][mob] - the user who placed this order
|
|
* * is_ordering_private - is the player ordering privatly. If FALSE it means they are using cargo budget
|
|
*/
|
|
/obj/machinery/materials_market/proc/find_order(mob/user, is_ordering_private)
|
|
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 == GALATIC_MATERIAL_ORDER && ( \
|
|
(!is_ordering_private && isnull(order.paying_account)) || \
|
|
(is_ordering_private && !isnull(order.paying_account) && order.orderer == user) \
|
|
))
|
|
return order
|
|
return null
|
|
|
|
/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_static_data(mob/user)
|
|
. = list()
|
|
.["CARGO_CRATE_VALUE"] = CARGO_CRATE_VALUE
|
|
|
|
/obj/machinery/materials_market/ui_data(mob/user)
|
|
. = list()
|
|
|
|
//can this player use cargo budget
|
|
var/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())
|
|
|
|
//if no cargo access then force private purchase
|
|
var/is_ordering_private = ordering_private || !can_buy_via_budget
|
|
|
|
//find current order based on ordering mode & player
|
|
var/datum/supply_order/current_order = find_order(user, is_ordering_private)
|
|
|
|
var/material_data
|
|
var/trend_string
|
|
var/color_string
|
|
var/sheet_to_buy
|
|
var/requested_amount
|
|
var/minimum_value_threshold = 0
|
|
var/elastic_mult = 1
|
|
for(var/datum/material/traded_mat as anything in SSstock_market.materials_prices)
|
|
//convert trend into text
|
|
switch(SSstock_market.materials_trends[traded_mat])
|
|
if(0)
|
|
trend_string = "neutral"
|
|
if(1)
|
|
trend_string = "up"
|
|
else
|
|
trend_string = "down"
|
|
|
|
//get mat color
|
|
var/initial_colors = initial(traded_mat.greyscale_color) || initial(traded_mat.color)
|
|
if(initial_colors)
|
|
color_string = splicetext(initial_colors, 7, length(initial_colors), "") //slice it to a standard 6 char hex
|
|
else
|
|
initial_colors = initial(traded_mat.color)
|
|
if(initial_colors)
|
|
color_string = initial_colors
|
|
else
|
|
color_string = COLOR_CYAN
|
|
|
|
//get sheet type from material
|
|
sheet_to_buy = initial(traded_mat.sheet_type)
|
|
if(!sheet_to_buy)
|
|
CRASH("Material with no sheet type being sold on materials market!")
|
|
|
|
//get the ordered amount from the order
|
|
requested_amount = 0
|
|
if(!isnull(current_order))
|
|
requested_amount = current_order.pack.contains[sheet_to_buy]
|
|
|
|
var/min_value_override = initial(traded_mat.minimum_value_override)
|
|
if(min_value_override)
|
|
minimum_value_threshold = min_value_override
|
|
else
|
|
minimum_value_threshold = round(initial(traded_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5)
|
|
|
|
//Pulling elastic modifier into data.
|
|
for(var/datum/export/material/market/export_est in GLOB.exports_list)
|
|
if(export_est.material_id == traded_mat)
|
|
elastic_mult = export_est.k_elasticity * 100
|
|
|
|
material_data += list(list(
|
|
"name" = initial(traded_mat.name),
|
|
"price" = SSstock_market.materials_prices[traded_mat],
|
|
"rarity" = initial(traded_mat.value_per_unit),
|
|
"threshold" = minimum_value_threshold,
|
|
"quantity" = SSstock_market.materials_quantity[traded_mat],
|
|
"trend" = trend_string,
|
|
"color" = color_string,
|
|
"requested" = requested_amount,
|
|
"elastic" = elastic_mult,
|
|
))
|
|
|
|
//get account balance
|
|
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
|
|
|
|
//is market crashing
|
|
var/market_crashing = FALSE
|
|
if(HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING))
|
|
market_crashing = TRUE
|
|
|
|
//get final order cost
|
|
var/current_cost = 0
|
|
if(!isnull(current_order))
|
|
current_cost = current_order.get_final_cost()
|
|
|
|
//pack data
|
|
.["catastrophe"] = market_crashing
|
|
.["materials"] = material_data
|
|
.["creditBalance"] = balance
|
|
.["orderBalance"] = current_cost
|
|
.["orderingPrive"] = ordering_private
|
|
.["canOrderCargo"] = can_buy_via_budget
|
|
.["updateTime"] = SSstock_market.next_fire - world.time
|
|
|
|
/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
|
|
var/can_buy_via_budget = (ACCESS_CARGO in used_id_card?.GetAccess())
|
|
|
|
//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(!can_buy_via_budget) //no cargo access then force private purchase
|
|
is_ordering_private = TRUE
|
|
|
|
switch(action)
|
|
if("buy")
|
|
var/material_str = params["material"]
|
|
var/quantity = text2num(params["quantity"])
|
|
|
|
//find material from its name
|
|
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!")
|
|
sheet_to_buy = initial(material_bought.sheet_type)
|
|
if(!sheet_to_buy)
|
|
CRASH("Material with no sheet type being sold on materials market!")
|
|
|
|
//get available bank account for purchasing
|
|
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
|
|
|
|
//sanity checks for available quantity & budget
|
|
if(quantity > SSstock_market.materials_quantity[material_bought])
|
|
say("Not enough materials on the market to purchase!")
|
|
return
|
|
|
|
var/cost = SSstock_market.materials_prices[material_bought] * quantity
|
|
|
|
var/list/things_to_order = list()
|
|
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
|
|
var/datum/supply_order/current_order = find_order(living_user, is_ordering_private)
|
|
if(!isnull(current_order))
|
|
// Check if this order exceeded the market limit
|
|
var/prior_sheets = current_order.pack.contains[sheet_to_buy]
|
|
if(prior_sheets + quantity > SSstock_market.materials_quantity[material_bought] )
|
|
say("There aren't enough sheets on the market! Please wait for more sheets to be traded before adding more.")
|
|
playsound(living_user, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
|
|
return
|
|
|
|
// Check if the order exceeded the purchase limit
|
|
var/prior_stacks = ROUND_UP(prior_sheets / MAX_STACK_SIZE)
|
|
if(prior_stacks >= MAX_STACK_LIMIT)
|
|
say("There are already 10 stacks of sheets on order! Please wait for them to arrive before ordering more.")
|
|
playsound(living_user, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
|
|
return
|
|
|
|
// Prevents you from ordering more than the available budget
|
|
var/datum/bank_account/paying_account = account_payable
|
|
if(!isnull(current_order.paying_account)) //order is already being paid by another account
|
|
paying_account = current_order.paying_account
|
|
if(current_order.get_final_cost() + cost > paying_account.account_balance)
|
|
say("Order exceeds available budget! Please send it before purchasing more.")
|
|
return
|
|
|
|
// Finally Append to this order
|
|
current_order.append_order(things_to_order, cost)
|
|
return TRUE
|
|
|
|
|
|
//Place a new order
|
|
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/disposable/materials/new_order = new(
|
|
pack = mineral_pack,
|
|
orderer = living_user,
|
|
orderer_rank = GALATIC_MATERIAL_ORDER,
|
|
orderer_ckey = living_user.ckey,
|
|
paying_account = is_ordering_private ? account_payable : null,
|
|
cost_type = MONEY_SYMBOL,
|
|
can_be_cancelled = FALSE
|
|
)
|
|
//first time order compute the correct cost and compare
|
|
if(new_order.get_final_cost() > account_payable.account_balance)
|
|
say("Not enough money to start purchase!")
|
|
qdel(new_order)
|
|
return
|
|
|
|
say("Thank you for your purchase! It will arrive on the next cargo shuttle!")
|
|
SSshuttle.shopping_list += new_order
|
|
return TRUE
|
|
|
|
if("toggle_budget")
|
|
if(!can_buy_via_budget)
|
|
return
|
|
ordering_private = !ordering_private
|
|
return TRUE
|
|
|
|
if("clear")
|
|
var/datum/supply_order/current_order = find_order(living_user, is_ordering_private)
|
|
if(!isnull(current_order))
|
|
SSshuttle.shopping_list -= current_order
|
|
qdel(current_order)
|
|
return TRUE
|
|
|
|
/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
|
|
/// Is this stock block currently updating its value with the market (aka fluid)?
|
|
var/fluid = FALSE
|
|
|
|
/obj/item/stock_block/Initialize(mapload)
|
|
. = ..()
|
|
addtimer(CALLBACK(src, PROC_REF(value_warning)), 1.5 MINUTES, TIMER_DELETE_ME)
|
|
addtimer(CALLBACK(src, PROC_REF(update_value)), 3 MINUTES, TIMER_DELETE_ME)
|
|
|
|
/obj/item/stock_block/examine(mob/user)
|
|
. = ..()
|
|
|
|
var/datum/material/export_mat = custom_materials[1]
|
|
var/quantity = custom_materials[export_mat] / SHEET_MATERIAL_AMOUNT
|
|
. += span_notice("\The [src] is worth [quantity * export_value] [MONEY_SYMBOL], from selling [quantity] sheets of [export_mat.name].")
|
|
|
|
if(fluid)
|
|
. += span_warning("\The [src] is currently liquid! Its 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 its value becomes liquid!")
|
|
|
|
/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()
|
|
export_value = SSstock_market.materials_prices[custom_materials[1]]
|
|
icon_state = "stock_block_liquid"
|
|
update_appearance(UPDATE_ICON_STATE)
|
|
visible_message(span_warning("\The [src] becomes liquid!"))
|
|
fluid = TRUE
|
|
|
|
#undef MAX_STACK_LIMIT
|
|
#undef GALATIC_MATERIAL_ORDER
|