mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
116 lines
4.3 KiB
Plaintext
116 lines
4.3 KiB
Plaintext
//Price fluxuations: swings -20% to +20%
|
|
//Prestige: money kept in Shoal account (each $250 gives -1%, max -20%)
|
|
//Loyal customer: each $100 spent gives -1% (max -10%)
|
|
|
|
var/datum/subsystem/trade_system/SStrade
|
|
|
|
/datum/subsystem/trade_system
|
|
name = "Trade System"
|
|
init_order = SS_INIT_OBJECT+0.1 //Always initialize just before objects
|
|
flags = SS_TICKER
|
|
wait = (3*SS_WAIT_ENGINES) //check in no more than once every thirty seconds
|
|
var/datum/trade_product/flash_sale_target = null //An extra 30% off!
|
|
var/list/all_twindows = list() //All trade windows
|
|
var/list/all_trade_merch = list() //The list of all trade products, kept as elements
|
|
var/list/trade_databank = list() //The above, converted to associative list format for use in UI
|
|
var/list/loyal_customers = list() //Associative list, associates face identities with cash spent.
|
|
|
|
/datum/subsystem/trade_system/New()
|
|
NEW_SS_GLOBAL(SStrade)
|
|
|
|
/datum/subsystem/trade_system/Initialize(timeofday)
|
|
for(var/path in subtypesof(/datum/trade_product))
|
|
all_trade_merch += new path
|
|
market_flux(FALSE)
|
|
..()
|
|
|
|
/datum/subsystem/trade_system/fire(resumed = FALSE)
|
|
if(flags & SS_NO_FIRE)
|
|
if(trader_account)
|
|
message_admins("Trade subsystem resumed, trader account found.")
|
|
flags &= ~SS_NO_FIRE
|
|
//if(state == SS_PAUSED)
|
|
//state = SS_RUNNING
|
|
return
|
|
if(trader_account)
|
|
if(prob(FLUX_CHANCE))
|
|
market_flux()
|
|
restock_chance()
|
|
flash_sale()
|
|
for(var/obj/structure/trade_window/TW in all_twindows)
|
|
nanomanager.update_uis(TW)
|
|
else
|
|
flags |= SS_NO_FIRE
|
|
//pause()
|
|
message_admins("Trade subsystem was paused due to lack of a trader account.")
|
|
|
|
/datum/subsystem/trade_system/proc/market_flux(var/update_windows = TRUE)
|
|
for(var/datum/trade_product/TP in all_trade_merch)
|
|
TP.flux_rate = 1+(rand(-20,20)/100) //Anywhere from 0.8 to 1.2
|
|
if(update_windows)
|
|
for(var/obj/structure/trade_window/TW in all_twindows)
|
|
TW.market_flux()
|
|
|
|
/datum/subsystem/trade_system/proc/flash_sale()
|
|
//Every 10 in the account gives a 1% chance for a flash sale, up to 100% at 1000
|
|
flash_sale_target = null
|
|
var/prestige = trader_account.money
|
|
if(prestige >= 1000 || prob(round(prestige/10)))
|
|
var/shuffled = shuffle(all_trade_merch)
|
|
for(var/datum/trade_product/TP in shuffled)
|
|
if(TP.totalsold >= TP.maxunits)
|
|
continue
|
|
flash_sale_target = TP
|
|
return
|
|
|
|
/datum/subsystem/trade_system/proc/restock_chance()
|
|
//Every 100 in the account gives a 1% chance for a restocked item, up to 10%
|
|
//In excess of 1000, you get extra rolls, up to three rolls.
|
|
var/sector_prestige = min(3000,trader_account.money)
|
|
while(sector_prestige>1000)
|
|
restock()
|
|
sector_prestige -= 1000
|
|
if(sector_prestige && prob(round(sector_prestige/100)))
|
|
restock()
|
|
|
|
/datum/subsystem/trade_system/proc/restock()
|
|
var/list/weighted_restocks = list()
|
|
for(var/datum/trade_product/TP in all_trade_merch)
|
|
if(!TP.can_restock())
|
|
continue
|
|
weighted_restocks[TP] = TP.restock_weight()
|
|
var/datum/trade_product/tostock = pickweight(weighted_restocks)
|
|
if(tostock)
|
|
tostock.restock()
|
|
|
|
/datum/subsystem/trade_system/proc/rebuild_databank(mob/user)
|
|
trade_databank.Cut() //empty the list
|
|
for(var/datum/trade_product/TP in all_trade_merch)
|
|
if(TP.totalsold >= TP.maxunits)
|
|
continue //Sold out
|
|
|
|
//Adds a list of lists. BYOND's default behavior is to append the contents of one list to the list
|
|
//So the outer list "dissolves", leaving only the list, which is associative and contains name, category, etc data
|
|
var/product_to_list = list()
|
|
product_to_list["name"] = TP.name
|
|
product_to_list["price"] = TP.current_price(user)
|
|
product_to_list["marketforces"] = round(100*(TP.flux_rate - 1))
|
|
product_to_list["flashed"] = (TP.isflashed() == 1 ? FALSE : TRUE)
|
|
product_to_list["category"] = TP.sales_category
|
|
product_to_list["remaining"] = TP.maxunits - TP.totalsold
|
|
trade_databank += list(product_to_list)
|
|
|
|
/datum/subsystem/trade_system/proc/shoal_prestige_factor()
|
|
if(trader_account.money >= 5000)
|
|
return 0.8
|
|
return 1-round(trader_account.money / 25000, 0.01)
|
|
|
|
/datum/subsystem/trade_system/proc/loyal_customer(mob/living/carbon/human/user)
|
|
if(!istype(user))
|
|
return 1.5
|
|
if(!(user.get_face_name() in loyal_customers))
|
|
return 1.5
|
|
if(loyal_customers[user.get_face_name()] >= 1000)
|
|
return 0.9
|
|
return 1-round(loyal_customers[user.get_face_name()]/10000,0.01) //1% off per $100 spent, up to 10% off
|