mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-13 02:11:44 +01:00
@@ -203,9 +203,6 @@
|
||||
name = T_BOARD("sensors console")
|
||||
build_path = /obj/machinery/computer/ship/sensors
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/area_atmos
|
||||
name = T_BOARD("area air control console")
|
||||
build_path = /obj/machinery/computer/area_atmos
|
||||
@@ -224,4 +221,9 @@
|
||||
/obj/item/weapon/circuitboard/shutoff_monitor
|
||||
name = T_BOARD("automatic shutoff valve monitor")
|
||||
build_path = /obj/machinery/computer/shutoff_monitor
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
|
||||
/obj/item/weapon/circuitboard/stockexchange
|
||||
name = T_BOARD("stock exchange console")
|
||||
build_path = /obj/machinery/computer/stockexchange
|
||||
origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 1)
|
||||
@@ -0,0 +1,125 @@
|
||||
/proc/consonant()
|
||||
return pick("B","C","D","F","G","H","J","K","L","M","N","P","Q","R","S","T","V","W","X","Y","Z")
|
||||
|
||||
/proc/vowel()
|
||||
return pick("A", "E", "I", "O", "U")
|
||||
|
||||
/proc/ucfirst(var/S)
|
||||
return "[uppertext(ascii2text(text2ascii(S, 1)))][copytext(S, 2)]"
|
||||
|
||||
/proc/ucfirsts(var/S)
|
||||
var/list/L = splittext(S, " ")
|
||||
var/list/M = list()
|
||||
for (var/P in L)
|
||||
M += ucfirst(P)
|
||||
return jointext(M, " ")
|
||||
|
||||
GLOBAL_LIST_EMPTY(FrozenAccounts)
|
||||
|
||||
/proc/list_frozen()
|
||||
for (var/A in GLOB.FrozenAccounts)
|
||||
to_chat(usr, "[A]: [length(GLOB.FrozenAccounts[A])] borrows")
|
||||
|
||||
/datum/article
|
||||
var/headline = "Something big is happening"
|
||||
var/subtitle = "Investors panic as stock market collapses"
|
||||
var/article = "God, it's going to be fun to randomly generate this."
|
||||
var/author = "P. Pubbie"
|
||||
var/spacetime = ""
|
||||
var/opinion = 0
|
||||
var/ticks = 0
|
||||
var/datum/stock/about = null
|
||||
var/outlet = ""
|
||||
var/static/list/outlets = list()
|
||||
var/static/list/default_tokens = list( \
|
||||
"buy" = list("buy!", "buy, buy, buy!", "get in now!", "ride the share value to the stars!"), \
|
||||
"company" = list("company", "corporation", "conglomerate", "enterprise", "venture"), \
|
||||
"complete" = list("complete", "total", "absolute", "incredible"), \
|
||||
"country" = list("Space", "Argentina", "Hungary", "United States of America", "United Space", "Space Federation", "Nanotrasen", "The Wizard Federation", "United Kingdom", "Poland", "The Syndicate", "Australia", "Serbia", "The European Union", "The Illuminati", "The New World Order", "Eurasian Union", "Asian Union", "United Arab Emirates", "Arabian League", "United States of Africa", "Mars Federation", "Allied Colonies of Jupiter", "Saturn's Ring", "Fringe Republic of Formerly Planet Pluto"), \
|
||||
"development" = list("development", "unfolding of events", "turn of events", "new shit"), \
|
||||
"dip" = list("dip", "fall", "plunge", "decrease"), \
|
||||
"excited" = list("excited", "euphoric", "exhilarated", "thrilled", "stimulated"), \
|
||||
"expand_influence" = list("expands their influence over", "continues to dominate", "gains traction in", "rolls their new product line out in"), \
|
||||
"failure" = list("failure", "meltdown", "breakdown", "crash", "defeat", "wreck"), \
|
||||
"famous" = list("famous", "prominent", "leading", "renowned", "expert"), \
|
||||
"hit_shelves" = list("hit the shelves", "appeared on the market", "came out", "was released"), \
|
||||
"industry" = list("industry", "sector"), \
|
||||
"industrial" = list("industrial"), \
|
||||
"jobs" = list("workers"), \
|
||||
"negative_outcome" = list("it's not leaving the shelves", "nobody seems to care", "it's a huge money sink", "they have already pulled all advertising and marketing support"), \
|
||||
"neutral_outcome" = list("it's not lifting off as expected", "it's not selling according to expectations", "it's only generating enough profit to cover the marketing and manufacturing costs", "it does not look like it will become a massive success", "it's experiencing modest sales"), \
|
||||
"positive_outcome" = list("it's already sold out", "it has already sold over one billion units", "suppliers cannot keep up with the wild demand", "several companies using this new technology are already reporting a projected increase in profits"), \
|
||||
"resounding" = list("resounding", "tremendous", "total", "massive", "terrific", "colossal"), \
|
||||
"rise" = list("rise", "increase", "fly off the positive side of the charts", "skyrocket", "lift off"), \
|
||||
"sell" = list("sell!", "sell, sell, sell!", "bail!", "abandon ship!", "get out before it's too late!", "evacuate!", "withdraw!"), \
|
||||
"signifying" = list("signifying", "indicating", "implying", "displaying", "suggesting"), \
|
||||
"sneak_peek" = list("review", "sneak peek", "preview", "exclusive look"), \
|
||||
"stock_market" = list("stock market", "stock exchange"), \
|
||||
"stockholder" = list("stockholder", "shareholder"), \
|
||||
"success" = list("success", "triumph", "victory"), \
|
||||
"this_time" = list("this week", "last week", "this month", "yesterday", "today", "a few days ago") \
|
||||
)
|
||||
|
||||
/datum/article/New()
|
||||
..()
|
||||
if ((outlets.len && !prob(100 / (outlets.len + 1))) || !outlets.len)
|
||||
var/ON = generateOutletName()
|
||||
if (!(ON in outlets))
|
||||
outlets[ON] = list()
|
||||
outlet = ON
|
||||
else
|
||||
outlet = pick(outlets)
|
||||
|
||||
var/list/authors = outlets[outlet]
|
||||
if ((authors.len && !prob(100 / (authors.len + 1))) || !authors.len)
|
||||
var/AN = generateAuthorName()
|
||||
outlets[outlet] += AN
|
||||
author = AN
|
||||
else
|
||||
author = pick(authors)
|
||||
|
||||
ticks = world.time
|
||||
|
||||
/datum/article/proc/generateOutletName()
|
||||
var/list/locations = list("Earth", "Luna", "Mars", "Saturn", "Jupiter", "Uranus", "Pluto", "Europa", "Io", "Phobos", "Deimos", "Space", "Venus", "Neptune", "Mercury", "Kalliope", "Ganymede", "Callisto", "Amalthea", "Himalia", "Orion", "Sybil", "Basil", "Badger", "Terry", "Artyom")
|
||||
var/list/nouns = list("Post", "Herald", "Sun", "Tribune", "Mail", "Times", "Journal", "Report")
|
||||
var/list/timely = list("Daily", "Hourly", "Weekly", "Biweekly", "Monthly", "Yearly")
|
||||
|
||||
switch(rand(1,2))
|
||||
if (1)
|
||||
return "The [pick(locations)] [pick(nouns)]"
|
||||
if (2)
|
||||
return "The [pick(timely)] [pick(nouns)]"
|
||||
|
||||
/datum/article/proc/generateAuthorName()
|
||||
switch(rand(1,3))
|
||||
if (1)
|
||||
return "[consonant()]. [pick(last_names)]"
|
||||
if (2)
|
||||
return "[prob(50) ? pick(first_names_male) : pick(first_names_female)] [consonant()].[prob(50) ? "[consonant()]. " : null] [pick(last_names)]"
|
||||
if (3)
|
||||
return "[prob(50) ? pick(first_names_male) : pick(first_names_female)] \"[prob(50) ? pick(first_names_male) : pick(first_names_female)]\" [pick(last_names)]"
|
||||
|
||||
/datum/article/proc/formatSpacetime()
|
||||
var/ticksc = round(ticks/100)
|
||||
ticksc = ticksc % 100000
|
||||
var/ticksp = "[ticksc]"
|
||||
while (length(ticksp) < 5)
|
||||
ticksp = "0[ticksp]"
|
||||
spacetime = "[ticksp][time2text(world.realtime, "MM")][time2text(world.realtime, "DD")][text2num(time2text(world.realtime, "YYYY"))+540]"
|
||||
|
||||
/datum/article/proc/formatArticle()
|
||||
if (spacetime == "")
|
||||
formatSpacetime()
|
||||
var/output = "<div class='article'><div class='headline'>[headline]</div><div class='subtitle'>[subtitle]</div><div class='article-body'>[article]</div><div class='author'>[author]</div><div class='timestamp'>[spacetime]</div></div>"
|
||||
return output
|
||||
|
||||
/datum/article/proc/detokenize(var/token_string, var/list/industry_tokens, var/list/product_tokens = list())
|
||||
var/list/T_list = default_tokens.Copy()
|
||||
for (var/I in industry_tokens)
|
||||
T_list[I] = industry_tokens[I]
|
||||
for (var/I in product_tokens)
|
||||
T_list[I] = list(product_tokens[I])
|
||||
for (var/I in T_list)
|
||||
token_string = replacetext(token_string, "%[I]%", pick(T_list[I]))
|
||||
return ucfirst(token_string)
|
||||
@@ -0,0 +1,336 @@
|
||||
/obj/machinery/computer/stockexchange
|
||||
name = "stock exchange computer"
|
||||
desc = "A console that connects to the galactic stock market. Stocks trading involves substantial risk of loss and is not suitable for every cargo technician."
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "stockmarket"
|
||||
icon_screen = "stocks"
|
||||
icon_keyboard = "stockmarket_key"
|
||||
var/logged_in = "Cargo Department"
|
||||
var/vmode = 1
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/machinery/computer/stockexchange/Initialize()
|
||||
. = ..()
|
||||
logged_in = "Cargo Department"
|
||||
|
||||
/obj/machinery/computer/stockexchange/attack_hand(mob/user)
|
||||
if(..(user))
|
||||
return
|
||||
|
||||
//if(!ai_control && issilicon(user))
|
||||
// to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
// return TRUE
|
||||
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/balance()
|
||||
if (!logged_in)
|
||||
return 0
|
||||
return SSsupply.points
|
||||
|
||||
///// MAIN TGUI SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
if ("logout")
|
||||
logged_in = null
|
||||
|
||||
if("stocks_buy")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
buy_some_shares(S, usr)
|
||||
|
||||
if("stocks_sell")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
sell_some_shares(S, usr)
|
||||
|
||||
if("stocks_check")
|
||||
var/dat = "<html><head><title>Stock Transaction Logs</title></head><body><h2>Stock Transaction Logs</h2><div><a href='?src=[REF(src)];show_logs=1'>Refresh</a></div></br>"
|
||||
for(var/D in GLOB.stockExchange.logs)
|
||||
var/datum/stock_log/L = D
|
||||
if(istype(L, /datum/stock_log/buy))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> bought <b>[L.stocks]</b> stocks at [L.shareprice] a share for <b>[L.money]</b> total credits in <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
if(istype(L, /datum/stock_log/sell))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> sold <b>[L.stocks]</b> stocks at [L.shareprice] a share for <b>[L.money]</b> total credits from <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
if(istype(L, /datum/stock_log/borrow))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> borrowed <b>[L.stocks]</b> stocks with a deposit of <b>[L.money]</b> credits in <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
var/datum/browser/popup = new(usr, "stock_logs", "Stock Transaction Logs", 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
if("stocks_archive")
|
||||
var/datum/stock/S = locate(params["share"])
|
||||
if (logged_in && logged_in != "")
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
LR[logged_in] = world.time
|
||||
var/dat = "<html><head><title>News feed for [S.name]</title></head><body><h2>News feed for [S.name]</h2><div><a href='?src=[REF(src)];archive=[REF(S)]'>Refresh</a></div>"
|
||||
dat += "<div><h3>Events</h3>"
|
||||
var/p = 0
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.hidden)
|
||||
continue
|
||||
if (p > 0)
|
||||
dat += "<hr>"
|
||||
dat += "<div><b>[E.current_title]</b></br>[E.current_desc]</div>"
|
||||
p++
|
||||
dat += "</div><hr><div><h3>Articles</h3>"
|
||||
p = 0
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (p > 0)
|
||||
dat += "<hr>"
|
||||
dat += "<div><b>[A.headline]</b><br><i>[A.subtitle]</i><br><br>[A.article]<br>- [A.author], [A.spacetime] (via <i>[A.outlet]</i>)</div>"
|
||||
p++
|
||||
dat += "</div></body></html>"
|
||||
var/datum/browser/popup = new(usr, "archive_[S.name]", "Stock News", 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
if("stocks_history")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
S.displayValues(usr)
|
||||
|
||||
if("stocks_cycle_view")
|
||||
vmode++
|
||||
if (vmode > 1)
|
||||
vmode = 0
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["stationName"] = using_map.station_name
|
||||
data["balance"] = balance()
|
||||
|
||||
if (vmode)
|
||||
data["viewMode"] = "Full"
|
||||
else
|
||||
data["viewMode"] = "Compressed"
|
||||
|
||||
for (var/datum/stock/S in GLOB.stockExchange.last_read)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
if (!(logged_in in LR))
|
||||
LR[logged_in] = 0
|
||||
|
||||
data["stocks"] = list()
|
||||
|
||||
if (vmode)
|
||||
for (var/datum/stock/S in GLOB.stockExchange.stocks)
|
||||
var/mystocks = 0
|
||||
if (logged_in && (logged_in in S.shareholders))
|
||||
mystocks = S.shareholders[logged_in]
|
||||
|
||||
var/value = 0
|
||||
if (!S.bankrupt)
|
||||
value = S.current_value
|
||||
|
||||
data["stocks"] += list(list(
|
||||
"REF" = REF(S),
|
||||
"valueChange" = S.disp_value_change, // > 0 is +, < 0 is -, else its =
|
||||
"bankrupt" = S.bankrupt,
|
||||
"ID" = S.short_name,
|
||||
"Name" = S.name,
|
||||
"Value" = value,
|
||||
"Owned" = mystocks,
|
||||
"Avail" = S.available_shares,
|
||||
"Products" = S.products,
|
||||
))
|
||||
|
||||
var/news = 0
|
||||
if (logged_in)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
var/lrt = LR[logged_in]
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (A.ticks > lrt)
|
||||
news = 1
|
||||
break
|
||||
if (!news)
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.last_change > lrt && !E.hidden)
|
||||
news = 1
|
||||
else
|
||||
for (var/datum/stock/S in GLOB.stockExchange.stocks)
|
||||
var/mystocks = 0
|
||||
if (logged_in && (logged_in in S.shareholders))
|
||||
mystocks = S.shareholders[logged_in]
|
||||
|
||||
var/unification = 0
|
||||
if (S.last_unification)
|
||||
unification = DisplayTimeText(world.time - S.last_unification)
|
||||
|
||||
data["stocks"] += list(list(
|
||||
"REF" = REF(S),
|
||||
"bankrupt" = S.bankrupt,
|
||||
"ID" = S.short_name,
|
||||
"Name" = S.name,
|
||||
"Owned" = mystocks,
|
||||
"Avail" = S.available_shares,
|
||||
"Unification" = unification,
|
||||
"Products" = S.products,
|
||||
))
|
||||
|
||||
var/news = 0
|
||||
if (logged_in)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
var/lrt = LR[logged_in]
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (A.ticks > lrt)
|
||||
news = 1
|
||||
break
|
||||
if (!news)
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.last_change > lrt && !E.hidden)
|
||||
news = 1
|
||||
break
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchange")
|
||||
ui.open()
|
||||
|
||||
///// HISTORY SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchangeHistory")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
//data["var"] = var
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("copypasta")
|
||||
//var/newvar = params["var"]
|
||||
// A demo of proper input sanitation.
|
||||
//var = CLAMP(newvar, min_val, max_val)
|
||||
. = TRUE
|
||||
|
||||
///// ARCHIVE SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchangeArchive")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
//data["var"] = var
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("copypasta")
|
||||
//var/newvar = params["var"]
|
||||
// A demo of proper input sanitation.
|
||||
//var = CLAMP(newvar, min_val, max_val)
|
||||
. = TRUE
|
||||
|
||||
///// PROCS /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/sell_some_shares(var/datum/stock/S, var/mob/user)
|
||||
if (!user || !S)
|
||||
return
|
||||
var/li = logged_in
|
||||
if (!li)
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/b = SSsupply.points
|
||||
var/avail = S.shareholders[logged_in]
|
||||
if (!avail)
|
||||
to_chat(user, "<span class='danger'>This account does not own any shares of [S.name]!</span>")
|
||||
return
|
||||
var/price = S.current_value
|
||||
var/amt = round(input(user, "How many shares? \n(Have: [avail], unit price: [price])", "Sell shares in [S.name]", 0) as num|null)
|
||||
amt = min(amt, S.shareholders[logged_in])
|
||||
|
||||
if (!user || (!(user in range(1, src)) && iscarbon(user)))
|
||||
return
|
||||
if (!amt)
|
||||
return
|
||||
if (li != logged_in)
|
||||
return
|
||||
b = SSsupply.points
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
|
||||
var/total = amt * S.current_value
|
||||
if (!S.sellShares(logged_in, amt))
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction.</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>Sold [amt] shares of [S.name] at [S.current_value] a share for [total] credits.</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/sell, user.name, S.name, amt, S.current_value, total)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/buy_some_shares(var/datum/stock/S, var/mob/user)
|
||||
if (!user || !S)
|
||||
return
|
||||
var/li = logged_in
|
||||
if (!li)
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/b = balance()
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/avail = S.available_shares
|
||||
var/price = S.current_value
|
||||
var/canbuy = round(b / price)
|
||||
var/amt = round(input(user, "How many shares? \n(Available: [avail], unit price: [price], can buy: [canbuy])", "Buy shares in [S.name]", 0) as num|null)
|
||||
if (!user || (!(user in range(1, src)) && iscarbon(user)))
|
||||
return
|
||||
if (li != logged_in)
|
||||
return
|
||||
b = balance()
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
|
||||
amt = min(amt, S.available_shares, round(b / S.current_value))
|
||||
if (!amt)
|
||||
return
|
||||
if (!S.buyShares(logged_in, amt))
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction.</span>")
|
||||
return
|
||||
|
||||
var/total = amt * S.current_value
|
||||
to_chat(user, "<span class='notice'>Bought [amt] shares of [S.name] at [S.current_value] a share for [total] credits.</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/buy, user.name, S.name, amt, S.current_value, total)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/do_borrowing_deal(var/datum/borrow/B, var/mob/user)
|
||||
if (B.stock.borrow(B, logged_in))
|
||||
to_chat(user, "<span class='notice'>You successfully borrowed [B.share_amount] shares. Deposit: [B.deposit].</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/borrow, user.name, B.stock.name, B.share_amount, B.deposit)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction. Check your account balance.</span>")
|
||||
|
||||
/obj/machinery/computer/stockexchange/Topic(href, href_list)
|
||||
if (..())
|
||||
return 1
|
||||
|
||||
if (!usr || (!(usr in range(1, src)) && iscarbon(usr)))
|
||||
usr.machine = src
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
@@ -0,0 +1,233 @@
|
||||
#define TIME_MULTIPLIER 0.7 // so I can speed up/slow down shit
|
||||
|
||||
/datum/stockEvent
|
||||
var/name = "event"
|
||||
var/next_phase = 0
|
||||
var/datum/stock/company = null
|
||||
var/current_title = "A company holding a pangalactic conference in the Seattle Conference Center, Seattle, Earth"
|
||||
var/current_desc = "We will continue to monitor their stocks as the situation unfolds."
|
||||
var/phase_id = 0
|
||||
var/hidden = 0
|
||||
var/finished = 0
|
||||
var/last_change = 0
|
||||
|
||||
/datum/stockEvent/process()
|
||||
if (finished)
|
||||
return
|
||||
if (world.time > next_phase)
|
||||
transition()
|
||||
|
||||
/datum/stockEvent/proc/transition()
|
||||
return
|
||||
|
||||
/datum/stockEvent/proc/spacetime(var/ticks)
|
||||
var/seconds = round(ticks / 10)
|
||||
var/minutes = round(seconds / 60)
|
||||
seconds -= minutes * 60
|
||||
return "[minutes] minute(s) and [seconds] second(s)"
|
||||
|
||||
/datum/stockEvent/product
|
||||
name = "product"
|
||||
var/product_name = ""
|
||||
var/datum/article/product_article = null
|
||||
var/effect = 0
|
||||
|
||||
/datum/stockEvent/product/New(var/datum/stock/S)
|
||||
company = S
|
||||
var/mins = rand(5*TIME_MULTIPLIER,20*TIME_MULTIPLIER)
|
||||
next_phase = mins * (600*TIME_MULTIPLIER) + world.time
|
||||
current_title = "Product demo"
|
||||
current_desc = S.industry.detokenize("[S.name] will unveil a new product on an upcoming %industrial% conference held at spacetime [spacetime(next_phase)]")
|
||||
S.addEvent(src)
|
||||
|
||||
|
||||
/datum/stockEvent/product/transition()
|
||||
last_change = world.time
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
product_name = company.industry.generateProductName(company.name)
|
||||
current_title = "Product release: [product_name]"
|
||||
current_desc = "[company.name] unveiled their newest product at a conference, [product_name]Product release is expected to happen at spacetime [spacetime(next_phase)]."
|
||||
var/datum/article/A = company.industry.generateInCharacterProductArticle(product_name, company)
|
||||
product_article = A
|
||||
effect = A.opinion + rand(-1, 1)
|
||||
company.affectPublicOpinion(effect)
|
||||
phase_id = 1
|
||||
if (1)
|
||||
finished = 1
|
||||
hidden = 1
|
||||
company.addArticle(product_article)
|
||||
effect += product_article.opinion * 5
|
||||
company.affectPublicOpinion(effect)
|
||||
phase_id = 2
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/bankruptcy
|
||||
name = "bankruptcy"
|
||||
var/effect = 0
|
||||
var/bailout_millions = 0
|
||||
|
||||
/datum/stockEvent/bankruptcy/New(var/datum/stock/S)
|
||||
hidden = 1
|
||||
company = S
|
||||
var/mins = rand(9*TIME_MULTIPLIER,60*TIME_MULTIPLIER)
|
||||
bailout_millions = rand(70, 190)
|
||||
next_phase = mins * 300*TIME_MULTIPLIER + world.time
|
||||
current_title = ""
|
||||
current_desc = ""
|
||||
S.addEvent(src)
|
||||
|
||||
/datum/stockEvent/bankruptcy/transition()
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
var/datum/article/A = generateBankruptcyArticle()
|
||||
if (!A.opinion)
|
||||
effect = rand(5) * (prob(50) ? -1 : 1)
|
||||
else
|
||||
effect = prob(25) ? -A.opinion * rand(8) : A.opinion * rand(4)
|
||||
company.addArticle(A)
|
||||
company.affectPublicOpinion(rand(-6, -3))
|
||||
hidden = 0
|
||||
current_title = "Bailout pending due to bankruptcy"
|
||||
current_desc = "The government prepared a press release, which will occur at spacetime [spacetime(next_phase)]."
|
||||
phase_id = 1
|
||||
if (1)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
finished = 1
|
||||
if (effect <= -5 && prob(10))
|
||||
current_title = "[company.name]: Complete crash"
|
||||
current_desc = "The company had gone bankrupt, was not bailed out and could not recover. No further stock trade will take place. All shares in the company are effectively worthless."
|
||||
company.bankrupt = 1
|
||||
for (var/X in company.shareholders)
|
||||
var/amt = company.shareholders[X]
|
||||
GLOB.stockExchange.balanceLog(X, -amt * company.current_value)
|
||||
company.shareholders = list()
|
||||
company.current_value = 0
|
||||
company.borrow_brokers = list()
|
||||
GLOB.stockExchange.generateStocks(1)
|
||||
|
||||
var/bailout = (effect > 0 && prob(80)) || (effect < 0 && prob(20))
|
||||
current_title = "[company.name] [bailout ? "bailed out" : "on a painful rebound"]"
|
||||
if (bailout)
|
||||
current_desc = "The company has been bailed out by the government. Investors are highly optimistic."
|
||||
company.affectPublicOpinion(abs(effect) * 2)
|
||||
else
|
||||
current_desc = "The company was not bailed out, but managed to crawl out of bankruptcy. Stockholder trust is severely dented."
|
||||
company.affectPublicOpinion(-abs(effect) / 2)
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/bankruptcy/proc/generateBankruptcyArticle()
|
||||
var/datum/article/A = new
|
||||
var/list/bankrupt_reason = list("investor pessimism", "failure of product lines", "economic recession", "overblown inflation", "overblown deflation", "collapsed pyramid schemes", "a Ponzi scheme", "economic terrorism", "extreme hedonism", "unfavourable economic climate", "rampant government corruption", "divine conspiracy", "some total bullshit", "volatile plans")
|
||||
A.about = company
|
||||
A.headline = pick( "[company.name] filing for bankruptcy", \
|
||||
"[company.name] unable to pay, investors run", \
|
||||
"[company.name] crashes, in foreclosure", \
|
||||
"[company.name] in dire need of credits")
|
||||
A.subtitle = "Investors panic, bailout pending"
|
||||
if (prob(15))
|
||||
A.opinion = rand(-1, 1)
|
||||
var/article = "Another one might bite the dust: [company.current_trend > 0 ? "despite their positive trend" : "in line with their failing model"], [company.name] files for bankruptcy citing [pick(bankrupt_reason)]. The president of %country% has been asked to bail the company out, "
|
||||
if (!A.opinion)
|
||||
article += "but no answer has been given by the government to date. Our tip to stay safe is: %sell%"
|
||||
else if (A.opinion > 0)
|
||||
article += "and the government responded positively. When the share value hits its lowest, it is a safe bet to %buy%"
|
||||
else
|
||||
article += "but the outlook is not good. For investors, now would be an ideal time to %sell%"
|
||||
A.article = A.detokenize(article, company.industry.tokens)
|
||||
return A
|
||||
|
||||
/datum/stockEvent/arrest
|
||||
name = "arrest"
|
||||
var/female = 0
|
||||
var/tname = "Elvis Presley"
|
||||
var/position = "CEO"
|
||||
var/offenses = "murder"
|
||||
var/effect = 0
|
||||
|
||||
/datum/stockEvent/arrest/New(var/datum/stock/S)
|
||||
hidden = 1
|
||||
company = S
|
||||
var/mins = rand(10*TIME_MULTIPLIER, 35*TIME_MULTIPLIER)
|
||||
next_phase = mins * 600*TIME_MULTIPLIER + world.time
|
||||
current_title = ""
|
||||
current_desc = ""
|
||||
female = prob(50)
|
||||
if (prob(50))
|
||||
position = "C[prob(20) ? vowel() : consonant()]O"
|
||||
else
|
||||
position = ucfirsts(company.industry.detokenize("Lead %industrial% Engineer"))
|
||||
offenses = ""
|
||||
var/list/O = list("corruption", "murder", "grand theft", "assault", "battery", "drug possession", "burglary", "theft", "grand sabotage", "bribery",
|
||||
"disorderly conduct", "treason", "sedition", "shoplifting", "tax evasion", "tax fraud", "insurance fraud", "perjury", "kidnapping", "manslaughter", "vandalism", "forgery", "extortion", "embezzlement",
|
||||
"public indecency", "public intoxication", "trespassing", "loitering", "littering", "vigilantism", "squatting", "panhandling", "arson", "spacepodjacking", "shuttlejacking", "carjacking", "singularityjacking",
|
||||
"dereliction of duty", "spacecraft piracy", "music piracy", "tabletop game piracy", "software piracy", "escaping from space prison", "seniornapping", "clownnapping", "corginapping", "catnapping",
|
||||
"sleeping on the job", "terrorism", "counterterrorism", "drug distribution", "insubordination", "jaywalking", "owning a computer", "owning a cellphone", "owning a PDA", "owning a pAI", "adultery",
|
||||
"committing an unnatural act with another person", "corrupting public morals", "skateboarding without a license", "shitcurity", "bestiality", "erotic roleplay", "accidentally strangling a prostitute")
|
||||
while (prob(60) && O.len > 2)
|
||||
var/offense = pick(O)
|
||||
O -= offense
|
||||
offense = "[prob(20) ? "attempted " : (prob(20) ? "being accessory to " : null)][offense][prob(5) ? " of the [pick("first", "second", "third", "fourth", "fifth", "sixth")] degree" : null]"
|
||||
if (offenses == "")
|
||||
offenses = offense
|
||||
else
|
||||
offenses += ", [offense]"
|
||||
offenses += " and [prob(20) ? "attempted " : null][pick(O)]" // lazy
|
||||
S.addEvent(src)
|
||||
|
||||
/datum/stockEvent/arrest/transition()
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
var/name_part1
|
||||
var/name_part2
|
||||
|
||||
name_part1 = pick("John ", "Jack ", "Jill ", "Peter ", "James ", "Lois ", "Zoey ")
|
||||
name_part2 = pick("Bull", "Palmer", "Glass", "Ruin", "McCory", "Batty", "Lane")
|
||||
tname = (name_part1 + name_part2)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
var/datum/article/A = generateArrestArticle()
|
||||
if (!A.opinion)
|
||||
effect = rand(5) * (prob(50) ? -1 : 1)
|
||||
else
|
||||
effect = prob(25) ? -A.opinion * rand(5) : A.opinion * rand(3)
|
||||
company.addArticle(A)
|
||||
company.affectPublicOpinion(rand(-3, -1))
|
||||
hidden = 0
|
||||
current_title = "Trial of [tname] ([position]) scheduled"
|
||||
current_desc = "[female ? "She": "He"] has been charged with [offenses]; the trial is scheduled to occur at spacetime [spacetime(next_phase)]."
|
||||
phase_id = 1
|
||||
if (1)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
finished = 1
|
||||
current_title = "[tname] [effect > 0 ? "acquitted" : "found guilty"]"
|
||||
if (effect > 0)
|
||||
current_desc = "The accused has been acquitted of all charges. Investors optimistic."
|
||||
else
|
||||
current_desc = "The accused has been found guilty of all charges. Investor trust takes massive hit."
|
||||
company.affectPublicOpinion(effect)
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/arrest/proc/generateArrestArticle()
|
||||
var/datum/article/A = new
|
||||
A.about = company
|
||||
A.headline = company.industry.detokenize(pick( \
|
||||
"[tname], [position] of [company.name] arrested", \
|
||||
"[position] of [company.name] facing jail time", \
|
||||
"[tname] behind bars", \
|
||||
"[position] of %industrial% company before trial", \
|
||||
"Police arrest [tname] in daring raid", \
|
||||
"Job vacancy ahead: [company.name]'s [position] in serious trouble"))
|
||||
A.subtitle = "[A.author] reporting directly from the courtroom"
|
||||
if (prob(15))
|
||||
A.opinion = rand(-1, 1)
|
||||
var/article = "[pick("Security", "Law enforcement")] forces issued a statement that [tname], the [position] of [company.name], the %famous% %industrial% %company% was arrested %this_time%. The trial has been scheduled and the statement reports that the arrested individual is being charged with [offenses]. "
|
||||
if (!A.opinion)
|
||||
article += "While we cannot predict the outcome of this trial, our tip to stay safe is: %sell%"
|
||||
else if (A.opinion > 0)
|
||||
article += "Our own investigation shows that these charges are baseless and the arrest is most likely a publicity stunt. Our advice? You should %buy%"
|
||||
else
|
||||
article += "[tname] has a prior history of similar misdeeds and we're confident the charges will stand. For investors, now would be an ideal time to %sell%"
|
||||
A.article = A.detokenize(article, company.industry.tokens)
|
||||
return A
|
||||
@@ -0,0 +1,233 @@
|
||||
/datum/industry
|
||||
var/name = "Industry"
|
||||
var/list/tokens = list()
|
||||
|
||||
var/list/title_templates = list("The brand new %product_name% by %company_name% will revolutionize %industry%", \
|
||||
"%jobs% rejoice as %product_name% hits shelves", \
|
||||
"Does %product_name% threaten to reorganize the %industrial% status quo?", \
|
||||
"%company_name% headed toward corporate renaissance with %product_name%")
|
||||
|
||||
var/list/title_templates_neutral = list("%product_name%: as if nothing happened", \
|
||||
"Nothing new but the name: %product_name% not quite exciting %jobs%", \
|
||||
"Same old %company_name%, same old product", \
|
||||
"%product_name% underwhelms, but sells")
|
||||
|
||||
var/list/title_templates_bad = list("%product_name% shaping up to be the disappointment of the century", \
|
||||
"Recipe for disaster: %company_name% releases %product_name%", \
|
||||
"Atrocious quality - %jobs% boycott %product_name%", \
|
||||
"%product_name%: Inside the worst product launch in recent history")
|
||||
|
||||
var/list/title_templates_ooc = list("%company_name% is looking to enter the %industry% playing field with %product_name%", \
|
||||
"%company_name% broadens spectrum, %product_name% is their latest and greatest")
|
||||
var/list/subtitle_templates = list( "%author% investigates whether or not you should invest!", \
|
||||
"%outlet%'s very own %author% takes it to the magnifying glass", \
|
||||
"%outlet% lets you know if you should use it", \
|
||||
"Read our top tips for investors", \
|
||||
"%author% wants you to know if it's a safe bet to buy")
|
||||
|
||||
/datum/industry/proc/generateProductName(var/company_name)
|
||||
return
|
||||
|
||||
/datum/industry/proc/generateInCharacterProductArticle(var/product_name, var/datum/stock/S)
|
||||
var/datum/article/A = new
|
||||
var/list/add_tokens = list("company_name" = S.name, "product_name" = product_name, "outlet" = A.outlet, "author" = A.author)
|
||||
A.about = S
|
||||
A.opinion = rand(-1, 1)
|
||||
|
||||
A.subtitle = A.detokenize(pick(subtitle_templates), tokens, add_tokens)
|
||||
var/article = {"%company_name% %expand_influence% %industry%. [ucfirst(product_name)] %hit_shelves% %this_time% "}
|
||||
if (A.opinion > 0)
|
||||
A.headline = A.detokenize(pick(title_templates), tokens, add_tokens)
|
||||
article += "but %positive_outcome%, %signifying% the %resounding% %success% the product is. The %stock_market% is %excited% over this %development%, and %stockholder% optimism is expected to %rise% as well as the stock value. Our advice: %buy%."
|
||||
else if (A.opinion == 0)
|
||||
A.headline = A.detokenize(pick(title_templates_neutral), tokens, add_tokens)
|
||||
article += "but %neutral_outcome%. For the average %stockholder%, no significant change on the market will be apparent over this %development%. Our advice is to continue investing as if this product was never released."
|
||||
else
|
||||
A.headline = A.detokenize(pick(title_templates_bad), tokens, add_tokens)
|
||||
article += "but %negative_outcome%. Following this %complete% %failure%, %stockholder% optimism and stock value are projected to %dip%. Our advice: %sell%."
|
||||
A.article = A.detokenize(article, tokens, add_tokens)
|
||||
return A
|
||||
|
||||
/datum/industry/proc/detokenize(var/str)
|
||||
for (var/T in tokens)
|
||||
str = replacetext(str, "%[T]%", pick(tokens[T]))
|
||||
return str
|
||||
|
||||
/datum/industry/agriculture
|
||||
name = "Agriculture"
|
||||
tokens = list( \
|
||||
"industry" = list("agriculture", "farming", "botany", "horticulture", "hydroponics"), \
|
||||
"industrial" = list("agricultural", "horticultural", "botanical"), \
|
||||
"jobs" = list("farmers", "agricultural experts", "botanists", "assistant gardeners")
|
||||
)
|
||||
title_templates = list( "The brand new %product_name% by %company_name% will revolutionize %industry%", \
|
||||
"%jobs% rejoice as %product_name% hits shelves", \
|
||||
"Does %product name% threaten to reorganize the %industrial% status quo?", \
|
||||
"Took it for a field trip: our first %sneak_peek% of %product_name%.", \
|
||||
"Reaping the fruits of %product_name% - %sneak_peek% by %author%", \
|
||||
"Cultivating a new %industrial% future with %product_name%", \
|
||||
"%company_name% grows and thrives: %product_name% now on the farmer's market", \
|
||||
"It's almost harvest season: %product_name% promises to ease your life", \
|
||||
"Become the best on the farmer's market with %product_name%", \
|
||||
"%product_name%: a gene-modified reimagination of an age-old classic")
|
||||
|
||||
title_templates_ooc = list( "%company_name% is looking to enter the %industry% playing field with %product_name%", \
|
||||
"A questionable decision: %product_name% grown on the soil of %company_name%", \
|
||||
"%company_name% broadens spectrum, %product_name% is their latest and greatest", \
|
||||
"Will %company_name% grow on %industrial% wasteland? Owners of %product_name% may decide", \
|
||||
"%company_name% looking to reap profits off the %industrial% sector with %product_name%")
|
||||
|
||||
/datum/industry/agriculture/generateProductName(var/company_name)
|
||||
var/list/products = list("water tank", "cattle prod", "scythe", "plough", "sickle", "cultivator", "loy", "spade", "hoe", "daisy grubber", "cotton gin")
|
||||
var/list/prefix = list("[company_name]'s ", "The [company_name] ", "The fully automatic ", "The full-duplex ", "The semi-automatic ", "The drone-mounted ", "The industry-leading ", "The world-class ")
|
||||
var/list/suffix = list(" of farming", " multiplex", " +[rand(1,15)]", " [consonant()][rand(1000, 9999)]", " hybrid", " maximus", " extreme")
|
||||
return "[pick(prefix)][pick(products)][pick(suffix)]. "
|
||||
|
||||
|
||||
|
||||
/datum/industry/it
|
||||
name = "Information Technology"
|
||||
tokens = list( \
|
||||
"industry" = list("information technology", "computing", "computer industry"), \
|
||||
"industrial" = list("information technological", "computing", "computer industrial"), \
|
||||
"jobs" = list("coders", "electricians", "engineers", "programmers", "devops experts", "developers")
|
||||
)
|
||||
|
||||
/datum/industry/it/proc/latin_number(n)
|
||||
if (n < 20 || !(n % 10))
|
||||
switch(n)
|
||||
if (0)
|
||||
return "Nihil"
|
||||
if (1)
|
||||
return "Unus"
|
||||
if (2)
|
||||
return "Duo"
|
||||
if (3)
|
||||
return "Tres"
|
||||
if (4)
|
||||
return "Quattour"
|
||||
if (5)
|
||||
return "Quinque"
|
||||
if (6)
|
||||
return "Sex"
|
||||
if (7)
|
||||
return "Septem"
|
||||
if (8)
|
||||
return "Octo"
|
||||
if (9)
|
||||
return "Novem"
|
||||
if (10)
|
||||
return "Decim"
|
||||
if (11)
|
||||
return "Undecim"
|
||||
if (12)
|
||||
return "Duodecim"
|
||||
if (13)
|
||||
return "Tredecim"
|
||||
if (14)
|
||||
return "Quattourdecim"
|
||||
if (15)
|
||||
return "Quindecim"
|
||||
if (16)
|
||||
return "Sedecim"
|
||||
if (17)
|
||||
return "Septdecim"
|
||||
if (18)
|
||||
return "Duodeviginti"
|
||||
if (19)
|
||||
return "Undeviginti"
|
||||
if (20)
|
||||
return "Viginti"
|
||||
if (30)
|
||||
return "Triginta"
|
||||
if (40)
|
||||
return "Quadriginta"
|
||||
if (50)
|
||||
return "Quinquaginta"
|
||||
if (60)
|
||||
return "Sexaginta"
|
||||
if (70)
|
||||
return "Septuaginta"
|
||||
if (80)
|
||||
return "Octoginta"
|
||||
if (90)
|
||||
return "Nonaginta"
|
||||
else
|
||||
return "[latin_number(n - (n % 10))] [lowertext(latin_number(n % 10))]"
|
||||
|
||||
/datum/industry/it/generateProductName(var/company_name)
|
||||
var/list/products = list("generator", "laptop", "keyboard", "memory card", "display", "operating system", "processor", "graphics card", "nanobots", "power supply", "pAI", "mech", "capacitor", "cell")
|
||||
var/list/prefix = list("The [company_name] ", "The high performance ", "The mobile ", "The portable ", "The professional ", "The extreme ", "The incredible ", "The blazing fast ", "The bleeding edge ", "The bluespace-powered ", null)
|
||||
var/L = pick(consonant(), "Seed ", "Radiant ", "Robust ", "Pentathon ", "Athlete ", "Phantom ", "Semper Fi ")
|
||||
var/N = rand(1, 99)
|
||||
var/prefix2 = "[L][N][prob(5) ? " " + latin_number(N) : null]"
|
||||
return "[pick(prefix)][prefix2] [pick(products)]. "
|
||||
|
||||
/datum/industry/communications
|
||||
name = "Communications"
|
||||
tokens = list( \
|
||||
"industry" = list("telecommunications", "telecomms"), \
|
||||
"industrial" = list("telecommunicational"), \
|
||||
"jobs" = list("electrical engineers", "microengineers", "developers")
|
||||
)
|
||||
|
||||
/datum/industry/communications/generateProductName(var/company_name)
|
||||
var/list/products = list("mobile phone", "PDA", "tablet computer", "newscaster", "social network")
|
||||
var/list/prefix = list("The [company_name] ", "The high performance ", "The mobile ", "The portable ", "The professional ", "The extreme ", "The incredible ", "The blazing fast ", "The bleeding edge ", null)
|
||||
var/L = pick("[lowertext(consonant())]Phone ", "Universe ", "Xperience ", "Next ", "Engin-Y ", "Cyborg ", "[consonant()]")
|
||||
var/N = rand(1,99)
|
||||
var/prefix2 = "[L][N][prob(25) ? pick(" Tiny", " Mini", " Micro", " Slim", " Water", " Air", " Fire", " Earth", " Nano", " Pico", " Femto", " Planck") : null]"
|
||||
return "[pick(prefix)][prefix2] [pick(products)]. "
|
||||
|
||||
/datum/industry/health
|
||||
name = "Medicine"
|
||||
tokens = list( \
|
||||
"industry" = list("medicine"), \
|
||||
"industrial" = list("medicinal"), \
|
||||
"jobs" = list("medical doctors", "nurses", "paramedics", "psychologists", "psychiatrists", "chemists")
|
||||
)
|
||||
|
||||
/datum/industry/health/generateProductName(var/company_name)
|
||||
var/list/prefix = list("amino", "nucleo", "nitro", "panto", "meth", "eth", "as", "algo", "coca", "hero", "lotsu", "opiod", "morph", "trinitro", "prop", "but", "acet", "acyclo", "lansop", "dyclo", "hydro", "oxycod", "vicod", "cannabi", "cryo", "dex", "chloro")
|
||||
var/list/suffix = list("phen", "pirin", "pyrine", "ane", "amphetamine", "prazoline", "ine", "yl", "amine", "aminophen", "one", "ide", "phenate", "anol", "toulene", "glycerine", "vir", "tol", "trinic", "oxide")
|
||||
var/list/uses = list("antidepressant", "analgesic", "anesthetic", "antiretroviral", "antiviral", "antibiotic", "cough drop", "depressant", "hangover cure", "homeopathic", "fertility drug", "hypnotic", "narcotic", "laxative", "multivitamin", "patch", "purgative", "relaxant", "steroid", "sleeping pill", "suppository", "tranquilizer")
|
||||
return "[pick(prefix)][pick(suffix)], the [pick(uses)]. "
|
||||
|
||||
/datum/industry/consumer
|
||||
name = "Consumer"
|
||||
tokens = list( \
|
||||
"industry" = list("shops", "stores"), \
|
||||
"industrial" = list("consumer industrial"), \
|
||||
"jobs" = list("shopkeepers", "assistants", "manual daytime hygiene engineers", "janitors", "chefs", "cooks")
|
||||
)
|
||||
|
||||
/datum/industry/consumer/generateProductName(var/company)
|
||||
var/list/meat = list("chicken", "lizard", "corgi", "monkey", "goat", "fly", "xenomorph", "human", "walrus", "wendigo", "bear", "clown", "turkey", "pork", "carp", "crab", "mimic", "mystery")
|
||||
var/list/qualifier = list("synthetic", "organic", "bio", "diet", "sugar-free", "paleolithic", "homeopathic", "recycled", "reclaimed", "vat-grown")
|
||||
return "The [pick(qualifier)] [pick(meat)] meat product line. "
|
||||
|
||||
/datum/industry/mining
|
||||
name = "Mining"
|
||||
tokens = list( \
|
||||
"industry" = list("mines", "large scale mining operations"), \
|
||||
"industrial" = list("resource acquisitional"), \
|
||||
"jobs" = list("shaft miners", "drill operators", "mining foremen")
|
||||
)
|
||||
|
||||
/datum/industry/mining/generateProductName(var/company)
|
||||
var/list/equipment = list("drill", "pickaxe", "shovel", "jackhammer", "mini-pickaxe", "power hammer", "power gloves", "power armor", "hardsuit", "kinetic accelerator", "resonator", "oxygen tank", "emergency bike horn")
|
||||
var/list/material = list("mauxite", "pharosium", "molitz", "adamantium", "mithril", "cobryl", "bohrum", "claretine", "viscerite", "syreline", "cerenkite", "plasmastone", "gold", "koshmarite", "phoron", "carbon dioxide", "powered")
|
||||
return "The [pick(material)] [pick(equipment)]. "
|
||||
|
||||
/datum/industry/defense
|
||||
name = "Defense"
|
||||
tokens = list ( \
|
||||
"industry" = list("defense", "warfare", "security", "law enforcement"), \
|
||||
"industrial" = list("defense"), \
|
||||
"jobs" = list("security officers", "government officials", "soldiers", "weapons engineers")
|
||||
)
|
||||
|
||||
/datum/industry/defense/generateProductName(var/company)
|
||||
var/list/equipment = list("energy gun", "laser gun", "machine gun", "grenade", "stun baton", "artillery", "bomb", "attack drone", "missile", "chem sprayer")
|
||||
var/list/material = list("bluespace", "stealth", "heat-seeking", "crime-seeking", "wide-range", "bioterror", "auto-reloading", "smart", "sentient", "rapid-fire", "species-targeting", "mass-market", "perpetual-motion", "nuclear", "fission", "fusion")
|
||||
return "The [pick(material)] [pick(equipment)]. "
|
||||
@@ -0,0 +1,14 @@
|
||||
/datum/stock_log
|
||||
var/user_name = ""
|
||||
var/company_name = ""
|
||||
var/shareprice
|
||||
var/money
|
||||
var/stocks
|
||||
var/time
|
||||
|
||||
|
||||
/datum/stock_log/buy
|
||||
|
||||
/datum/stock_log/sell
|
||||
|
||||
/datum/stock_log/borrow
|
||||
@@ -0,0 +1,168 @@
|
||||
/datum/stockMarket
|
||||
var/list/stocks = list()
|
||||
var/list/balances = list()
|
||||
var/list/last_read = list()
|
||||
var/list/stockBrokers = list()
|
||||
var/list/logs = list()
|
||||
|
||||
/datum/stockMarket/New()
|
||||
..()
|
||||
generateBrokers()
|
||||
generateStocks()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/stockMarket/proc/balanceLog(var/whose, var/net)
|
||||
if (!(whose in balances))
|
||||
balances[whose] = net
|
||||
else
|
||||
balances[whose] += net
|
||||
/datum/stockMarket/proc/generateBrokers()
|
||||
stockBrokers = list()
|
||||
var/list/fnames = list("Goldman", "Edward", "James", "Luis", "Alexander", "Walter", "Eugene", "Mary", "Morgan", "Jane", "Elizabeth", "Xavier", "Hayden", "Samuel", "Lee")
|
||||
var/list/names = list("Johnson", "Rothschild", "Sachs", "Stanley", "Hepburn", "Brown", "McColl", "Fischer", "Edwards", "Becker", "Witter", "Walker", "Lambert", "Smith", "Montgomery", "Lynch", "Roosevelt", "Lehman")
|
||||
var/list/locations = list("Earth", "Luna", "Mars", "Saturn", "Jupiter", "Uranus", "Pluto", "Europa", "Io", "Phobos", "Deimos", "Space", "Venus", "Neptune", "Mercury", "Kalliope", "Ganymede", "Callisto", "Amalthea", "Himalia", "Sybil", "Basil", "Badger", "Terry", "Artyom")
|
||||
var/list/first = list("The", "First", "Premier", "Finest", "Prime")
|
||||
var/list/company = list("Investments", "Securities", "Corporation", "Bank", "Brokerage", "& Co.", "Brothers", "& Sons", "Investement Firm", "Union", "Partners", "Capital", "Trade", "Holdings")
|
||||
for(var/i in 1 to 5)
|
||||
var/pname = ""
|
||||
switch (rand(1,5))
|
||||
if (1)
|
||||
pname = "[prob(10) ? pick(first) + " " : null][pick(names)] [pick(company)]"
|
||||
if (2)
|
||||
pname = "[pick(names)] & [pick(names)][prob(25) ? " " + pick(company) : null]"
|
||||
if (3)
|
||||
pname = "[prob(45) ? pick(first) + " " : null][pick(locations)] [pick(company)]"
|
||||
if (4)
|
||||
pname = "[prob(10) ? "The " : null][pick(names)] [pick(locations)] [pick(company)]"
|
||||
if (5)
|
||||
pname = "[prob(10) ? "The " : null][pick(fnames)] [pick(names)][prob(10) ? " " + pick(company) : null]"
|
||||
if (pname in stockBrokers)
|
||||
i--
|
||||
continue
|
||||
stockBrokers += pname
|
||||
|
||||
/datum/stockMarket/proc/generateDesignation(var/name)
|
||||
if (length(name) <= 4)
|
||||
return uppertext(name)
|
||||
var/list/w = splittext(name, " ")
|
||||
if (w.len >= 2)
|
||||
var/d = ""
|
||||
for(var/i in 1 to min(5, w.len))
|
||||
d += uppertext(ascii2text(text2ascii(w[i], 1)))
|
||||
return d
|
||||
else
|
||||
var/d = uppertext(ascii2text(text2ascii(name, 1)))
|
||||
for(var/i in 2 to length(name))
|
||||
if (prob(100 / i))
|
||||
d += uppertext(ascii2text(text2ascii(name, i)))
|
||||
return d
|
||||
|
||||
/datum/stockMarket/proc/generateStocks(var/amt = 15)
|
||||
var/list/fruits = list("Banana", "Mimana", "Watermelon", "Ambrosia", "Pomegranate", "Reishi", "Papaya", "Mango", "Tomato", "Conkerberry", "Wood", "Lychee", "Mandarin", "Harebell", "Pumpkin", "Rhubarb", "Tamarillo", "Yantok", "Ziziphus", "Oranges", "Gatfruit", "Daisy", "Kudzu")
|
||||
var/list/tech_prefix = list("Nano", "Cyber", "Funk", "Astro", "Fusion", "Tera", "Exo", "Star", "Virtual", "Plasma", "Robust", "Bit", "Future", "Hugbox", "Carbon", "Nerf", "Buff", "Nova", "Space", "Meta", "Cyber")
|
||||
var/list/tech_short = list("soft", "tech", "prog", "tec", "tek", "ware", "", "gadgets", "nics", "tric", "trasen", "tronic", "coin")
|
||||
var/list/random_nouns = list("Johnson", "Cluwne", "General", "Specific", "Master", "King", "Queen", "Table", "Rupture", "Dynamic", "Massive", "Mega", "Giga", "Certain", "Singulo", "State", "National", "International", "Interplanetary", "Sector", "Planet", "Burn", "Robust", "Exotic", "Solar", "Lunar", "Chelp", "Corgi", "Lag", "Lizard")
|
||||
var/list/company = list("Company", "Factory", "Incorporated", "Industries", "Group", "Consolidated", "GmbH", "LLC", "Ltd", "Inc.", "Association", "Limited", "Software", "Technology", "Programming", "IT Group", "Electronics", "Nanotechnology", "Farms", "Stores", "Mobile", "Motors", "Electric", "Designs", "Energy", "Pharmaceuticals", "Communications", "Wholesale", "Holding", "Health", "Machines", "Astrotech", "Gadgets", "Kinetics")
|
||||
for (var/i = 1, i <= amt, i++)
|
||||
var/datum/stock/S = new
|
||||
var/sname = ""
|
||||
switch (rand(1,6))
|
||||
if(1)
|
||||
while (sname == "" || sname == "FAG") // honestly it's a 0.6% chance per round this happens - or once in 166 rounds - so i'm accounting for it before someone yells at me
|
||||
sname = "[consonant()][vowel()][consonant()]"
|
||||
if (2)
|
||||
sname = "[pick(tech_prefix)][pick(tech_short)][prob(20) ? " " + pick(company) : null]"
|
||||
if (3 to 4)
|
||||
var/fruit = pick(fruits)
|
||||
fruits -= fruit
|
||||
sname = "[prob(10) ? "The " : null][fruit][prob(40) ? " " + pick(company): null]"
|
||||
if (5 to 6)
|
||||
var/pname = pick(random_nouns)
|
||||
random_nouns -= pname
|
||||
switch (rand(1,3))
|
||||
if (1)
|
||||
sname = "[pname] & [pname]"
|
||||
if (2)
|
||||
sname = "[pname] [pick(company)]"
|
||||
if (3)
|
||||
sname = "[pname]"
|
||||
S.name = sname
|
||||
S.short_name = generateDesignation(S.name)
|
||||
S.current_value = rand(10, 125)
|
||||
var/dv = rand(10, 40) / 10
|
||||
S.fluctuational_coefficient = prob(50) ? (1 / dv) : dv
|
||||
S.average_optimism = rand(-10, 10) / 100
|
||||
S.optimism = S.average_optimism + (rand(-40, 40) / 100)
|
||||
S.current_trend = rand(-200, 200) / 10
|
||||
S.last_trend = S.current_trend
|
||||
S.disp_value_change = rand(-1, 1)
|
||||
S.speculation = rand(-20, 20)
|
||||
S.average_shares = round(rand(500, 10000) / 10)
|
||||
S.outside_shareholders = rand(1000, 30000)
|
||||
S.available_shares = rand(200000, 800000)
|
||||
S.fluctuation_rate = rand(6, 20)
|
||||
S.generateIndustry()
|
||||
S.generateEvents()
|
||||
stocks += S
|
||||
last_read[S] = list()
|
||||
|
||||
/datum/stockMarket/process()
|
||||
for (var/stock in stocks)
|
||||
var/datum/stock/S = stock
|
||||
S.process()
|
||||
|
||||
/datum/stockMarket/proc/add_log(var/log_type, var/user, var/company_name, var/stocks, var/shareprice, var/money)
|
||||
var/datum/stock_log/L = new log_type
|
||||
L.user_name = user
|
||||
L.company_name = company_name
|
||||
L.stocks = stocks
|
||||
L.shareprice = shareprice
|
||||
L.money = money
|
||||
L.time = time2text(world.timeofday, "hh:mm")
|
||||
logs += L
|
||||
|
||||
GLOBAL_DATUM_INIT(stockExchange, /datum/stockMarket, new)
|
||||
|
||||
/proc/plotBarGraph(var/list/points, var/base_text, var/width=400, var/height=400)
|
||||
var/output = "<table style='border:1px solid black; border-collapse: collapse; width: [width]px; height: [height]px'>"
|
||||
if (points.len && height > 20 && width > 20)
|
||||
var/min = points[1]
|
||||
var/max = points[1]
|
||||
for (var/v in points)
|
||||
if (v < min)
|
||||
min = v
|
||||
if (v > max)
|
||||
max = v
|
||||
var/cells = (height - 20) / 20
|
||||
if (cells > round(cells))
|
||||
cells = round(cells) + 1
|
||||
var/diff = max - min
|
||||
var/ost = diff / cells
|
||||
if (min > 0)
|
||||
min = max(min - ost, 0)
|
||||
diff = max - min
|
||||
ost = diff / cells
|
||||
var/cval = max
|
||||
var/cwid = width / (points.len + 1)
|
||||
for (var/y = cells, y > 0, y--)
|
||||
if (y == cells)
|
||||
output += "<tr>"
|
||||
else
|
||||
output += "<tr style='border:none; border-top:1px solid #00ff00; height: 20px'>"
|
||||
for (var/x = 0, x <= points.len, x++)
|
||||
if (x == 0)
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; font-size:10px; color:#00ff00; background:black; text-align:right; vertical-align:bottom'>[round(cval - ost)]</td>"
|
||||
else
|
||||
var/v = points[x]
|
||||
if (v >= cval)
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; background:#0000ff'> </td>"
|
||||
else
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; background:black'> </td>"
|
||||
output += "</tr>"
|
||||
cval -= ost
|
||||
output += "<tr><td style='font-size:10px; height: 20px; width: 100%; background:black; color:green; text-align:center' colspan='[points.len + 1]'>[base_text]</td></tr>"
|
||||
else
|
||||
output += "<tr><td style='width:[width]px; height:[height]px; background: black'></td></tr>"
|
||||
output += "<tr><td style='font-size:10px; background:black; color:green; text-align:center'>[base_text]</td></tr>"
|
||||
|
||||
return "[output]</table>"
|
||||
@@ -0,0 +1,308 @@
|
||||
/datum/borrow
|
||||
var/broker = ""
|
||||
var/borrower = ""
|
||||
var/datum/stock/stock = null
|
||||
var/lease_expires = 0
|
||||
var/lease_time = 0
|
||||
var/grace_time = 0
|
||||
var/grace_expires = 0
|
||||
var/share_amount = 0
|
||||
var/share_debt = 0
|
||||
var/deposit = 0
|
||||
var/offer_expires = 0
|
||||
|
||||
/datum/stock
|
||||
var/name = "Stock"
|
||||
var/short_name = "STK"
|
||||
var/desc = "A company that does not exist."
|
||||
var/list/values = list()
|
||||
var/current_value = 10
|
||||
var/last_value = 10
|
||||
var/list/products = list()
|
||||
|
||||
var/performance = 0 // The current performance of the company. Tends itself to 0 when no events happen.
|
||||
|
||||
// These variables determine standard fluctuational patterns for this stock.
|
||||
var/fluctuational_coefficient = 1 // How much the price fluctuates on an average daily basis
|
||||
var/average_optimism = 0 // The history of shareholder optimism of this stock
|
||||
var/current_trend = 0
|
||||
var/last_trend = 0
|
||||
var/speculation = 0
|
||||
var/bankrupt = 0
|
||||
|
||||
var/disp_value_change = 0
|
||||
var/optimism = 0
|
||||
var/last_unification = 0
|
||||
var/average_shares = 100
|
||||
var/outside_shareholders = 10000 // The amount of offstation people holding shares in this company. The higher it is, the more fluctuation it causes.
|
||||
var/available_shares = 500000
|
||||
|
||||
var/list/borrow_brokers = list()
|
||||
var/list/shareholders = list()
|
||||
var/list/borrows = list()
|
||||
var/list/events = list()
|
||||
var/list/articles = list()
|
||||
var/fluctuation_rate = 15
|
||||
var/fluctuation_counter = 0
|
||||
var/datum/industry/industry = null
|
||||
|
||||
/datum/stock/proc/addEvent(var/datum/stockEvent/E)
|
||||
events |= E
|
||||
|
||||
/datum/stock/proc/addArticle(var/datum/article/A)
|
||||
if (!(A in articles))
|
||||
articles.Insert(1, A)
|
||||
A.ticks = world.time
|
||||
|
||||
/datum/stock/proc/generateEvents()
|
||||
var/list/types = typesof(/datum/stockEvent) - /datum/stockEvent
|
||||
for (var/T in types)
|
||||
generateEvent(T)
|
||||
|
||||
/datum/stock/proc/generateEvent(var/T)
|
||||
var/datum/stockEvent/E = new T(src)
|
||||
addEvent(E)
|
||||
|
||||
/datum/stock/proc/affectPublicOpinion(var/boost)
|
||||
optimism += rand(0, 500) / 500 * boost
|
||||
average_optimism += rand(0, 150) / 5000 * boost
|
||||
speculation += rand(-1, 50) / 10 * boost
|
||||
performance += rand(0, 150) / 100 * boost
|
||||
|
||||
/datum/stock/proc/generateIndustry()
|
||||
if (findtext(name, "Farms"))
|
||||
industry = new /datum/industry/agriculture
|
||||
else if (findtext(name, "Software") || findtext(name, "Programming") || findtext(name, "IT Group") || findtext(name, "Electronics") || findtext(name, "Electric") || findtext(name, "Nanotechnology"))
|
||||
industry = new /datum/industry/it
|
||||
else if (findtext(name, "Mobile") || findtext(name, "Communications"))
|
||||
industry = new /datum/industry/communications
|
||||
else if (findtext(name, "Pharmaceuticals") || findtext(name, "Health"))
|
||||
industry = new /datum/industry/health
|
||||
else if (findtext(name, "Wholesale") || findtext(name, "Stores"))
|
||||
industry = new /datum/industry/consumer
|
||||
else
|
||||
var/ts = typesof(/datum/industry) - /datum/industry
|
||||
var/in_t = pick(ts)
|
||||
industry = new in_t
|
||||
for (var/i = 0, i < rand(2, 5), i++)
|
||||
products += industry.generateProductName(name)
|
||||
|
||||
/datum/stock/proc/frc(amt)
|
||||
var/shares = available_shares + outside_shareholders * average_shares
|
||||
var/fr = amt / 100 / shares * fluctuational_coefficient * fluctuation_rate * max(-(current_trend / 100), 1)
|
||||
if ((fr < 0 && speculation < 0) || (fr > 0 && speculation > 0))
|
||||
fr *= max(abs(speculation) / 5, 1)
|
||||
else
|
||||
fr /= max(abs(speculation) / 5, 1)
|
||||
return fr
|
||||
|
||||
/datum/stock/proc/supplyGrowth(amt)
|
||||
var/fr = frc(amt)
|
||||
available_shares += amt
|
||||
if (abs(fr) < 0.0001)
|
||||
return
|
||||
current_value -= fr * current_value
|
||||
|
||||
/datum/stock/proc/supplyDrop(amt)
|
||||
supplyGrowth(-amt)
|
||||
|
||||
/datum/stock/proc/fluctuate()
|
||||
var/change = rand(-100, 100) / 10 + optimism * rand(200) / 10
|
||||
optimism -= (optimism - average_optimism) * (rand(10,80) / 1000)
|
||||
var/shift_score = change + current_trend
|
||||
var/as_score = abs(shift_score)
|
||||
var/sh_change_dev = rand(-10, 10) / 10
|
||||
var/sh_change = shift_score / (as_score + 100) + sh_change_dev
|
||||
var/shareholder_change = round(sh_change)
|
||||
outside_shareholders += shareholder_change
|
||||
var/share_change = shareholder_change * average_shares
|
||||
if (as_score > 20 && prob(as_score / 4))
|
||||
var/avg_change_dev = rand(-10, 10) / 10
|
||||
var/avg_change = shift_score / (as_score + 100) + avg_change_dev
|
||||
average_shares += avg_change
|
||||
share_change += outside_shareholders * avg_change
|
||||
|
||||
var/cv = last_value
|
||||
supplyDrop(share_change)
|
||||
available_shares += share_change // temporary
|
||||
|
||||
if (prob(25))
|
||||
average_optimism = max(min(average_optimism + (rand(-3, 3) - current_trend * 0.15) / 100, 1), -1)
|
||||
|
||||
var/aspec = abs(speculation)
|
||||
if (prob((aspec - 75) * 2))
|
||||
speculation += rand(-4, 4)
|
||||
else
|
||||
if (prob(50))
|
||||
speculation += rand(-4, 4)
|
||||
else
|
||||
speculation += rand(-400, 0) / 1000 * speculation
|
||||
if (prob(1) && prob(5)) // pop that bubble
|
||||
speculation += rand(-4000, 0) / 1000 * speculation
|
||||
|
||||
if (current_value < 5)
|
||||
current_value = 5
|
||||
|
||||
if (performance != 0)
|
||||
performance = rand(900,1050) / 1000 * performance
|
||||
if (abs(performance) < 0.2)
|
||||
performance = 0
|
||||
|
||||
disp_value_change = (cv < current_value) ? 1 : ((cv > current_value) ? -1 : 0)
|
||||
last_value = current_value
|
||||
if (values.len >= 50)
|
||||
values.Cut(1,2)
|
||||
values += current_value
|
||||
|
||||
if (current_value < 10)
|
||||
unifyShares()
|
||||
|
||||
last_trend = current_trend
|
||||
current_trend += rand(-200, 200) / 100 + optimism * rand(200) / 10 + max(50 - abs(speculation), 0) / 50 * rand(0, 200) / 1000 * (-current_trend) + max(speculation - 50, 0) * rand(0, 200) / 1000 * speculation / 400
|
||||
|
||||
/datum/stock/proc/unifyShares()
|
||||
for (var/I in shareholders)
|
||||
var/shr = shareholders[I]
|
||||
if (shr % 2)
|
||||
sellShares(I, 1)
|
||||
shr -= 1
|
||||
shareholders[I] /= 2
|
||||
if (!shareholders[I])
|
||||
shareholders -= I
|
||||
for (var/datum/borrow/B in borrow_brokers)
|
||||
B.share_amount = round(B.share_amount / 2)
|
||||
B.share_debt = round(B.share_debt / 2)
|
||||
for (var/datum/borrow/B in borrows)
|
||||
B.share_amount = round(B.share_amount / 2)
|
||||
B.share_debt = round(B.share_debt / 2)
|
||||
average_shares /= 2
|
||||
available_shares /= 2
|
||||
current_value *= 2
|
||||
last_unification = world.time
|
||||
|
||||
/datum/stock/process()
|
||||
for (var/B in borrows)
|
||||
var/datum/borrow/borrow = B
|
||||
if (world.time > borrow.grace_expires)
|
||||
modifyAccount(borrow.borrower, -max(current_value * borrow.share_debt, 0), 1)
|
||||
borrows -= borrow
|
||||
if (borrow.borrower in GLOB.FrozenAccounts)
|
||||
GLOB.FrozenAccounts[borrow.borrower] -= borrow
|
||||
if (length(GLOB.FrozenAccounts[borrow.borrower]) == 0)
|
||||
GLOB.FrozenAccounts -= borrow.borrower
|
||||
qdel(borrow)
|
||||
else if (world.time > borrow.lease_expires)
|
||||
if (borrow.borrower in shareholders)
|
||||
var/amt = shareholders[borrow.borrower]
|
||||
if (amt > borrow.share_debt)
|
||||
shareholders[borrow.borrower] -= borrow.share_debt
|
||||
borrows -= borrow
|
||||
if (borrow.borrower in GLOB.FrozenAccounts)
|
||||
GLOB.FrozenAccounts[borrow.borrower] -= borrow
|
||||
if (length(GLOB.FrozenAccounts[borrow.borrower]) == 0)
|
||||
GLOB.FrozenAccounts -= borrow.borrower
|
||||
qdel(borrow)
|
||||
else
|
||||
shareholders -= borrow.borrower
|
||||
borrow.share_debt -= amt
|
||||
if (bankrupt)
|
||||
return
|
||||
for (var/B in borrow_brokers)
|
||||
var/datum/borrow/borrow = B
|
||||
if (borrow.offer_expires < world.time)
|
||||
borrow_brokers -= borrow
|
||||
qdel(borrow)
|
||||
if (prob(5))
|
||||
generateBrokers()
|
||||
fluctuation_counter++
|
||||
if (fluctuation_counter >= fluctuation_rate)
|
||||
for (var/E in events)
|
||||
var/datum/stockEvent/EV = E
|
||||
EV.process()
|
||||
fluctuation_counter = 0
|
||||
fluctuate()
|
||||
|
||||
/datum/stock/proc/generateBrokers()
|
||||
if (borrow_brokers.len > 2)
|
||||
return
|
||||
if (!GLOB.stockExchange.stockBrokers.len)
|
||||
GLOB.stockExchange.generateBrokers()
|
||||
var/broker = pick(GLOB.stockExchange.stockBrokers)
|
||||
var/datum/borrow/B = new
|
||||
B.broker = broker
|
||||
B.stock = src
|
||||
B.lease_time = rand(4, 7) * 600
|
||||
B.grace_time = rand(1, 3) * 600
|
||||
B.share_amount = rand(1, 10) * 100
|
||||
B.deposit = rand(20, 70) / 100
|
||||
B.share_debt = B.share_amount
|
||||
B.offer_expires = rand(5, 10) * 600 + world.time
|
||||
borrow_brokers += B
|
||||
|
||||
/datum/stock/proc/modifyAccount(whose, by, force=0)
|
||||
if (SSsupply.points)
|
||||
if (by < 0 && SSsupply.points + by < 0 && !force)
|
||||
return 0
|
||||
SSsupply.points += by
|
||||
GLOB.stockExchange.balanceLog(whose, by)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/borrow(var/datum/borrow/B, var/who)
|
||||
if (B.lease_expires)
|
||||
return 0
|
||||
B.lease_expires = world.time + B.lease_time
|
||||
var/old_d = B.deposit
|
||||
var/d_amt = B.deposit * current_value * B.share_amount
|
||||
if (!modifyAccount(who, -d_amt))
|
||||
B.lease_expires = 0
|
||||
B.deposit = old_d
|
||||
return 0
|
||||
B.deposit = d_amt
|
||||
if (!(who in shareholders))
|
||||
shareholders[who] = B.share_amount
|
||||
else
|
||||
shareholders[who] += B.share_amount
|
||||
borrow_brokers -= B
|
||||
borrows += B
|
||||
B.borrower = who
|
||||
B.grace_expires = B.lease_expires + B.grace_time
|
||||
if (!(who in GLOB.FrozenAccounts))
|
||||
GLOB.FrozenAccounts[who] = list(B)
|
||||
else
|
||||
GLOB.FrozenAccounts[who] += B
|
||||
return 1
|
||||
|
||||
/datum/stock/proc/buyShares(var/who, var/howmany)
|
||||
if (howmany <= 0)
|
||||
return
|
||||
howmany = round(howmany)
|
||||
var/loss = howmany * current_value
|
||||
if (available_shares < howmany)
|
||||
return 0
|
||||
if (modifyAccount(who, -loss))
|
||||
supplyDrop(howmany)
|
||||
if (!(who in shareholders))
|
||||
shareholders[who] = howmany
|
||||
else
|
||||
shareholders[who] += howmany
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/sellShares(var/whose, var/howmany)
|
||||
if (howmany < 0)
|
||||
return
|
||||
howmany = round(howmany)
|
||||
var/gain = howmany * current_value
|
||||
if (shareholders[whose] < howmany)
|
||||
return 0
|
||||
if (modifyAccount(whose, gain))
|
||||
supplyGrowth(howmany)
|
||||
shareholders[whose] -= howmany
|
||||
if (shareholders[whose] <= 0)
|
||||
shareholders -= whose
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/displayValues(var/mob/user)
|
||||
user << browse(plotBarGraph(values, "[name] share value per share"), "window=stock_[name];size=450x450")
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 170 KiB |
+22
-12
@@ -1229,6 +1229,15 @@
|
||||
},
|
||||
/turf/simulated/floor/wood,
|
||||
/area/groundbase/dorms/room2)
|
||||
"dA" = (
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/stockexchange{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"dB" = (
|
||||
/obj/machinery/firealarm{
|
||||
dir = 8
|
||||
@@ -5692,9 +5701,7 @@
|
||||
/turf/simulated/floor/outdoors/newdirt/virgo3c,
|
||||
/area/groundbase/command/hop)
|
||||
"qN" = (
|
||||
/obj/effect/landmark{
|
||||
name = "lightsout"
|
||||
},
|
||||
/obj/structure/table/standard,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"qP" = (
|
||||
@@ -6064,7 +6071,6 @@
|
||||
/area/groundbase/dorms/room3)
|
||||
"rN" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/table/standard,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
@@ -7079,6 +7085,11 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/table/standard,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"uT" = (
|
||||
@@ -12693,10 +12704,12 @@
|
||||
/area/groundbase/cargo/office)
|
||||
"Le" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/table/standard,
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/landmark{
|
||||
name = "lightsout"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"Lf" = (
|
||||
@@ -13341,10 +13354,10 @@
|
||||
pixel_x = 4;
|
||||
pixel_y = -2
|
||||
},
|
||||
/obj/item/weapon/stamp/cargo,
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on{
|
||||
dir = 1
|
||||
},
|
||||
/obj/item/weapon/stamp/accepted,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"MR" = (
|
||||
@@ -15272,9 +15285,6 @@
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/obj/item/weapon/packageWrap,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/groundbase/cargo/office)
|
||||
"Sm" = (
|
||||
@@ -28784,7 +28794,7 @@ Lc
|
||||
Oi
|
||||
xK
|
||||
uS
|
||||
Lc
|
||||
qN
|
||||
FR
|
||||
FR
|
||||
Lc
|
||||
@@ -29351,9 +29361,9 @@ Ki
|
||||
za
|
||||
za
|
||||
Vu
|
||||
qN
|
||||
Lc
|
||||
rj
|
||||
FR
|
||||
dA
|
||||
XU
|
||||
wm
|
||||
dH
|
||||
|
||||
@@ -12391,13 +12391,13 @@
|
||||
pixel_x = 4;
|
||||
pixel_y = -2
|
||||
},
|
||||
/obj/item/weapon/stamp/cargo,
|
||||
/obj/machinery/light/floortube{
|
||||
dir = 1;
|
||||
pixel_y = 6
|
||||
},
|
||||
/obj/machinery/camera/network/cargo,
|
||||
/obj/item/device/retail_scanner/cargo,
|
||||
/obj/item/weapon/stamp/accepted,
|
||||
/turf/simulated/floor/tiled/eris/steel/brown_platform,
|
||||
/area/quartermaster/storage)
|
||||
"BN" = (
|
||||
@@ -13427,6 +13427,9 @@
|
||||
"Eh" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/structure/bed/chair/office/dark{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/tiled/eris/steel/cargo,
|
||||
/area/quartermaster/storage)
|
||||
"Ei" = (
|
||||
@@ -21315,6 +21318,10 @@
|
||||
"Vp" = (
|
||||
/obj/structure/table/standard,
|
||||
/obj/machinery/cell_charger,
|
||||
/obj/item/weapon/module/power_control,
|
||||
/obj/item/weapon/cell{
|
||||
maxcharge = 2000
|
||||
},
|
||||
/turf/simulated/floor/tiled/eris/steel/cargo,
|
||||
/area/quartermaster/storage)
|
||||
"Vq" = (
|
||||
@@ -21622,15 +21629,13 @@
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"Wc" = (
|
||||
/obj/structure/table/standard,
|
||||
/obj/item/weapon/module/power_control,
|
||||
/obj/item/weapon/cell{
|
||||
maxcharge = 2000
|
||||
},
|
||||
/obj/item/device/radio/intercom{
|
||||
dir = 4;
|
||||
pixel_x = 24
|
||||
},
|
||||
/obj/machinery/computer/stockexchange{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/tiled/eris/steel/cargo,
|
||||
/area/quartermaster/storage)
|
||||
"We" = (
|
||||
|
||||
@@ -10657,14 +10657,13 @@
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/engineering/engine_eva)
|
||||
"aBo" = (
|
||||
/obj/machinery/disposal,
|
||||
/obj/structure/disposalpipe/trunk,
|
||||
/obj/effect/floor_decal/borderfloor{
|
||||
dir = 9
|
||||
},
|
||||
/obj/effect/floor_decal/corner/brown/border{
|
||||
dir = 9
|
||||
},
|
||||
/obj/machinery/computer/stockexchange,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"aBp" = (
|
||||
@@ -29373,6 +29372,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/table/standard,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"pbJ" = (
|
||||
@@ -29775,7 +29775,12 @@
|
||||
name = "\improper Telecomms Entrance"
|
||||
})
|
||||
"pGq" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/floor_decal/borderfloor/corner{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/floor_decal/corner/brown/bordercorner{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"pGr" = (
|
||||
@@ -32934,7 +32939,6 @@
|
||||
pixel_x = 4;
|
||||
pixel_y = -2
|
||||
},
|
||||
/obj/item/weapon/stamp/cargo,
|
||||
/obj/effect/floor_decal/borderfloor{
|
||||
dir = 1
|
||||
},
|
||||
@@ -32947,6 +32951,7 @@
|
||||
/obj/effect/floor_decal/corner/brown/bordercorner2{
|
||||
dir = 4
|
||||
},
|
||||
/obj/item/weapon/stamp/accepted,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"tos" = (
|
||||
@@ -34280,7 +34285,6 @@
|
||||
/turf/simulated/floor,
|
||||
/area/maintenance/station/cargo)
|
||||
"uMR" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/floor_decal/borderfloor{
|
||||
dir = 8
|
||||
},
|
||||
@@ -34291,6 +34295,9 @@
|
||||
dir = 8;
|
||||
pixel_x = -24
|
||||
},
|
||||
/obj/structure/bed/chair/office/dark{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"uOm" = (
|
||||
@@ -34602,6 +34609,10 @@
|
||||
/obj/effect/floor_decal/corner/brown/border{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/disposalpipe/trunk{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/disposal,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"vcG" = (
|
||||
@@ -47073,9 +47084,9 @@ tos
|
||||
ayY
|
||||
aBo
|
||||
uMR
|
||||
gVf
|
||||
pGq
|
||||
dXC
|
||||
aAB
|
||||
fMr
|
||||
shZ
|
||||
azc
|
||||
kNs
|
||||
|
||||
@@ -168,8 +168,8 @@
|
||||
pixel_x = 24
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
d2 = 2
|
||||
d2 = 2;
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/tcommsat/computer)
|
||||
@@ -179,8 +179,8 @@
|
||||
/area/space)
|
||||
"aA" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/cyan{
|
||||
icon_state = "map";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "map"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/engineering/engine_room)
|
||||
@@ -353,8 +353,8 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/black{
|
||||
dir = 6
|
||||
@@ -368,8 +368,8 @@
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
@@ -386,8 +386,8 @@
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
@@ -405,8 +405,8 @@
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
@@ -468,8 +468,8 @@
|
||||
/area/engineering/engine_room)
|
||||
"aY" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/cyan{
|
||||
icon_state = "intact";
|
||||
dir = 5
|
||||
dir = 5;
|
||||
icon_state = "intact"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
@@ -495,8 +495,8 @@
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/engineering/engine_room)
|
||||
@@ -541,8 +541,8 @@
|
||||
/area/tcommsat/chamber)
|
||||
"bg" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/machinery/power/apc{
|
||||
dir = 1;
|
||||
@@ -709,8 +709,8 @@
|
||||
pixel_y = 0
|
||||
},
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/engineering/engine_room)
|
||||
@@ -747,8 +747,8 @@
|
||||
/area/tcommsat/chamber)
|
||||
"bw" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/machinery/power/apc{
|
||||
dir = 2;
|
||||
@@ -798,8 +798,8 @@
|
||||
name_tag = "MiniTest"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
@@ -933,8 +933,8 @@
|
||||
pixel_y = 0
|
||||
},
|
||||
/obj/machinery/light{
|
||||
icon_state = "tube1";
|
||||
dir = 8
|
||||
dir = 8;
|
||||
icon_state = "tube1"
|
||||
},
|
||||
/turf/simulated/floor/bluegrid{
|
||||
name = "Mainframe Base";
|
||||
@@ -1115,8 +1115,8 @@
|
||||
pixel_x = -32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/hallway/secondary/engineering_hallway)
|
||||
@@ -1227,9 +1227,9 @@
|
||||
external_pressure_bound = 140;
|
||||
external_pressure_bound_default = 140;
|
||||
icon_state = "map_vent_out";
|
||||
use_power = 1;
|
||||
pressure_checks = 0;
|
||||
pressure_checks_default = 0
|
||||
pressure_checks_default = 0;
|
||||
use_power = 1
|
||||
},
|
||||
/turf/simulated/floor/bluegrid{
|
||||
name = "Mainframe Base";
|
||||
@@ -1260,10 +1260,10 @@
|
||||
initialize_directions = 1;
|
||||
internal_pressure_bound = 4000;
|
||||
internal_pressure_bound_default = 4000;
|
||||
use_power = 1;
|
||||
pressure_checks = 2;
|
||||
pressure_checks_default = 2;
|
||||
pump_direction = 0
|
||||
pump_direction = 0;
|
||||
use_power = 1
|
||||
},
|
||||
/turf/simulated/floor/bluegrid{
|
||||
name = "Mainframe Base";
|
||||
@@ -2299,8 +2299,8 @@
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 10
|
||||
dir = 10;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/bar)
|
||||
@@ -2682,8 +2682,8 @@
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/cafeteria)
|
||||
@@ -2874,8 +2874,8 @@
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/bridge)
|
||||
@@ -3314,15 +3314,15 @@
|
||||
/area/shuttle/overmapdemo)
|
||||
"mj" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 10
|
||||
dir = 10;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/bar)
|
||||
"nM" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/cafeteria)
|
||||
@@ -3332,8 +3332,8 @@
|
||||
/area/bridge)
|
||||
"pG" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/bridge)
|
||||
@@ -3363,8 +3363,8 @@
|
||||
/area/bridge)
|
||||
"rK" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 10
|
||||
dir = 10;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/bluegrid{
|
||||
name = "Mainframe Base";
|
||||
@@ -3399,15 +3399,15 @@
|
||||
/area/shuttle/overmapdemo)
|
||||
"xM" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 5
|
||||
dir = 5;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/cafeteria)
|
||||
"xX" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/medical/medbay)
|
||||
@@ -3439,8 +3439,8 @@
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/hallway/primary/fore)
|
||||
@@ -3466,8 +3466,8 @@
|
||||
/area/shuttle/overmapdemo)
|
||||
"OA" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 10
|
||||
dir = 10;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/medical/medbay)
|
||||
@@ -3487,8 +3487,8 @@
|
||||
/area/bridge)
|
||||
"Ug" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/medical/medbay2)
|
||||
@@ -3500,8 +3500,8 @@
|
||||
/area/shuttle/overmapdemo)
|
||||
"Vf" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/crew_quarters/bar)
|
||||
@@ -3521,8 +3521,8 @@
|
||||
/area/shuttle/overmapdemo)
|
||||
"Yb" = (
|
||||
/obj/machinery/camera/network/civilian{
|
||||
icon_state = "camera";
|
||||
dir = 9
|
||||
dir = 9;
|
||||
icon_state = "camera"
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/medical/medbay2)
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
import { useBackend } from "../backend";
|
||||
import { Box, Button, Divider, Section, Table } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const StockExchange = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
stationName,
|
||||
balance,
|
||||
viewMode,
|
||||
stocks = [],
|
||||
} = data;
|
||||
|
||||
let subTemplate = <StockExchangeFullView />;
|
||||
|
||||
if (viewMode === "Full") {
|
||||
subTemplate = <StockExchangeFullView />;
|
||||
} else if (viewMode === "Compressed") {
|
||||
subTemplate = <StockExchangeCompactView />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Window
|
||||
width={600}
|
||||
height={600}
|
||||
resizable>
|
||||
<Window.Content scrollable>
|
||||
<Section title={`${stationName} Stock Exchange`}>
|
||||
<span>Welcome, <b>{stationName} Cargo Department</b> | </span>
|
||||
<span><b>Credits:</b> {balance}</span><br />
|
||||
<b>View mode: </b>
|
||||
<Button content={viewMode}
|
||||
onClick={() => act("stocks_cycle_view")} /><br />
|
||||
|
||||
<b>Stock Transaction Log: </b>
|
||||
<Button icon="list"
|
||||
content="Check"
|
||||
onClick={() => act("stocks_check")} /><br />
|
||||
<b>This is a work in progress. Certain features may not be available.</b>
|
||||
</Section>
|
||||
<Section title="Listed Stocks">
|
||||
{subTemplate}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const StockExchangeFullView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
stocks = [],
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<b>Actions:</b> + Buy, - Sell, (A)rchives, (H)istory
|
||||
<Divider />
|
||||
<Table>
|
||||
<Table.Row>
|
||||
<Table.Cell bold>
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
ID
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Name
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Value
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Owned
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Avail
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Actions
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Divider />
|
||||
{stocks.map(stock => (
|
||||
<Table.Row key={stock.ID}>
|
||||
<Table.Cell bold>
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
{stock.ID}
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
{stock.Name}
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
{stock.Value}
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
{stock.Owned}
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
{stock.Avail}
|
||||
</Table.Cell>
|
||||
<Table.Cell color="label">
|
||||
<Button icon="plus"
|
||||
disabled={false}
|
||||
onClick={() => act("stocks_buy", { share: stock.REF })} />
|
||||
<Button icon="minus"
|
||||
disabled={false}
|
||||
onClick={() => act("stocks_sell", { share: stock.REF })} /><br />
|
||||
<Button content="A"
|
||||
onClick={() => act("stocks_archive", { share: stock.REF })} />
|
||||
<Button content="H"
|
||||
onClick={() => act("stocks_history", { share: stock.REF })} /><br />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const StockExchangeCompactView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
stocks = [],
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{stocks.map(stock => (
|
||||
<Box key={stock.ID}>
|
||||
<span>{stock.name}</span> <span>{stock.ID}</span>{stock.bankrupt === 1 && <b color="red">BANKRUPT</b> }<br />
|
||||
<b>Unified shares</b> {stock.Unification} ago.<br />
|
||||
<b>Current value per share:</b> {stock.Value} | <Button content="View history" onClick={() => act("stocks_history", { share: stock.REF })} /><br />
|
||||
You currently own <b>{stock.Owned}</b> shares in this company.<br />
|
||||
There are {stock.Avail} purchasable shares on the market currently.<br />
|
||||
|
||||
{stock.bankrupt === 1 ? <span>You cannot buy or sell shares in a bankrupt company!</span>
|
||||
: <span><Button content="Buy shares" onClick={() => act("stocks_buy", { share: stock.REF })} /> | <Button content="Sell shares" onClick={() => act("stocks_sell", { share: stock.REF })} /></span> }
|
||||
<br />
|
||||
<b>Prominent products:</b><br />
|
||||
<i>{stock.Products}</i><br />
|
||||
<Button content="View news archives" onClick={() => act("stocks_archive", { share: stock.REF })} /> { /* [news ? " <span style='color:red'>(updated)</span>" : null] */ }
|
||||
<Divider />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const StockExchangeHistory = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
stocks = [],
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{stocks.map(stock => (
|
||||
<Box key={stock.ID}>
|
||||
<span>{stock.name}</span> <span>{stock.ID}</span>{stock.bankrupt === 1 && <b color="red">BANKRUPT</b> }<br />
|
||||
<b>Unified shares</b> {stock.Unification} ago.<br />
|
||||
<b>Current value per share:</b> {stock.Value} | <Button content="View history" onClick={() => act("stocks_history", { share: stock.REF })} /><br />
|
||||
You currently own <b>{stock.Owned}</b> shares in this company.<br />
|
||||
There are {stock.Avail} purchasable shares on the market currently.<br />
|
||||
|
||||
{stock.bankrupt === 1 ? <span>You cannot buy or sell shares in a bankrupt company!</span>
|
||||
: <span><Button content="Buy shares" onClick={() => act("stocks_buy", { share: stock.REF })} /> | <Button content="Sell shares" onClick={() => act("stocks_sell", { share: stock.REF })} /></span> }
|
||||
<br />
|
||||
<b>Prominent products:</b><br />
|
||||
<i>{stock.Products}</i><br />
|
||||
<Button content="View news archives" onClick={() => act("stocks_archive", { share: stock.REF })} /> { /* [news ? " <span style='color:red'>(updated)</span>" : null] */ }
|
||||
<Divider />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const StockExchangeArchive = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
stocks = [],
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{stocks.map(stock => (
|
||||
<Box key={stock.ID}>
|
||||
<span>{stock.name}</span> <span>{stock.ID}</span>{stock.bankrupt === 1 && <b color="red">BANKRUPT</b> }<br />
|
||||
<b>Unified shares</b> {stock.Unification} ago.<br />
|
||||
<b>Current value per share:</b> {stock.Value} | <Button content="View history" onClick={() => act("stocks_history", { share: stock.REF })} /><br />
|
||||
You currently own <b>{stock.Owned}</b> shares in this company.<br />
|
||||
There are {stock.Avail} purchasable shares on the market currently.<br />
|
||||
|
||||
{stock.bankrupt === 1 ? <span>You cannot buy or sell shares in a bankrupt company!</span>
|
||||
: <span><Button content="Buy shares" onClick={() => act("stocks_buy", { share: stock.REF })} /> | <Button content="Sell shares" onClick={() => act("stocks_sell", { share: stock.REF })} /></span> }
|
||||
<br />
|
||||
<b>Prominent products:</b><br />
|
||||
<i>{stock.Products}</i><br />
|
||||
<Button content="View news archives" onClick={() => act("stocks_archive", { share: stock.REF })} /> { /* [news ? " <span style='color:red'>(updated)</span>" : null] */ }
|
||||
<Divider />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7
-4
@@ -84,7 +84,6 @@
|
||||
#include "code\__defines\shuttle.dm"
|
||||
#include "code\__defines\sound.dm"
|
||||
#include "code\__defines\spaceman_dmm.dm"
|
||||
#include "code\__defines\span_vr.dm"
|
||||
#include "code\__defines\species_languages.dm"
|
||||
#include "code\__defines\species_languages_vr.dm"
|
||||
#include "code\__defines\sprite_sheets.dm"
|
||||
@@ -3731,7 +3730,6 @@
|
||||
#include "code\modules\research\designs\weapons_vr.dm"
|
||||
#include "code\modules\research\designs\xenoarch_toys.dm"
|
||||
#include "code\modules\research\designs\xenobio_toys.dm"
|
||||
#include "code\modules\research\designs\xenobio_toys_vr.dm"
|
||||
#include "code\modules\research\designs\circuits\ai_modules.dm"
|
||||
#include "code\modules\research\designs\circuits\ai_modules_vr.dm"
|
||||
#include "code\modules\research\designs\circuits\circuits.dm"
|
||||
@@ -3841,6 +3839,13 @@
|
||||
#include "code\modules\spells\targeted\projectile\fireball.dm"
|
||||
#include "code\modules\spells\targeted\projectile\magic_missile.dm"
|
||||
#include "code\modules\spells\targeted\projectile\projectile.dm"
|
||||
#include "code\modules\stockmarket\articles.dm"
|
||||
#include "code\modules\stockmarket\computer.dm"
|
||||
#include "code\modules\stockmarket\events.dm"
|
||||
#include "code\modules\stockmarket\industries.dm"
|
||||
#include "code\modules\stockmarket\logs.dm"
|
||||
#include "code\modules\stockmarket\stockmarket.dm"
|
||||
#include "code\modules\stockmarket\stocks.dm"
|
||||
#include "code\modules\surgery\_defines.dm"
|
||||
#include "code\modules\surgery\bones.dm"
|
||||
#include "code\modules\surgery\encased.dm"
|
||||
@@ -3975,7 +3980,6 @@
|
||||
#include "code\modules\vore\eating\silicon_vr.dm"
|
||||
#include "code\modules\vore\eating\simple_animal_vr.dm"
|
||||
#include "code\modules\vore\eating\slipvore_vr.dm"
|
||||
#include "code\modules\vore\eating\stumblevore_vr.dm"
|
||||
#include "code\modules\vore\eating\transforming_vr.dm"
|
||||
#include "code\modules\vore\eating\vore_vr.dm"
|
||||
#include "code\modules\vore\eating\vorehooks_vr.dm"
|
||||
@@ -4074,7 +4078,6 @@
|
||||
#include "code\modules\xenobio\items\slimepotions.dm"
|
||||
#include "code\modules\xenobio\items\slimepotions_vr.dm"
|
||||
#include "code\modules\xenobio\items\weapons.dm"
|
||||
#include "code\modules\xenobio\items\weapons_vr.dm"
|
||||
#include "code\modules\xenobio\machinery\processor.dm"
|
||||
#include "code\modules\xgm\xgm_gas_data.dm"
|
||||
#include "code\modules\xgm\xgm_gas_mixture.dm"
|
||||
|
||||
Reference in New Issue
Block a user