Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Representative Stock Market [NOT YET] #2631

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions code/__DEFINES/text.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// BYOND's string procs don't support being used on datum references (as in it doesn't look for a name for stringification)
/// We just use this macro to ensure that we will only pass strings to this BYOND-level function without developers needing to really worry about it.
#define LOWER_TEXT(thing) lowertext(UNLINT("[thing]"))

/// Folder directory for strings
#define STRING_DIRECTORY "strings"

#define ALPHABET list("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")
#define VOWELS list("a", "e", "i", "o", "u")
#define CONSONANTS list("b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z")
106 changes: 106 additions & 0 deletions code/controllers/subsystem/economy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,18 @@ SUBSYSTEM_DEF(economy)
///The modifier multiplied to the value of cargo pack prices.
var/pack_price_modifier = 1
var/market_crashing = FALSE
//STOCK MARKET VARS
var/list/stocks = list()
var/list/balances = list()
var/list/last_read = list()
var/list/stock_brokers = list()

/datum/controller/subsystem/economy/Initialize(timeofday)
var/budget_to_hand_out = round(budget_pool / department_accounts.len)
for(var/A in department_accounts)
new /datum/bank_account/department(A, budget_to_hand_out)
generateBrokers()
generateStocks()
return ..()

/datum/controller/subsystem/economy/Recover()
Expand All @@ -66,6 +73,9 @@ SUBSYSTEM_DEF(economy)
station_target = max(round(temporary_total / max(bank_accounts_by_id.len * 2, 1)) + station_target_buffer, 1)
// if(!market_crashing)
// price_update() Fucks up Workshop, I'll figure out how to make it override soon:tm: - Kirie
for(var/stock in stocks)
var/datum/stock/S = stock
S.process()

/**
* Handy proc for obtaining a department's bank account, given the department ID, AKA the define assigned for what department they're under.
Expand Down Expand Up @@ -113,3 +123,99 @@ SUBSYSTEM_DEF(economy)
return 1
inflation_value = max(round(((station_total / bank_accounts_by_id.len) / station_target), 0.1), 1.0)
return inflation_value

//STOCK MARKET PROCS
/datum/controller/subsystem/economy/proc/balanceLog(whose, net)
if (!(whose in balances))
balances[whose] = net
else
balances[whose] += net

/datum/controller/subsystem/economy/proc/generateBrokers()
stock_brokers = 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/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] District [rand(4,24)] [pick(company)]"
if (4)
pname = "[prob(10) ? "The " : null][pick(names)] District [rand(4,24)] [pick(company)]"
if (5)
pname = "[prob(10) ? "The " : null][pick(fnames)] [pick(names)][prob(10) ? " " + pick(company) : null]"
if (pname in stock_brokers)
i--
continue
stock_brokers += pname

/datum/controller/subsystem/economy/proc/generateDesignation(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/controller/subsystem/economy/proc/generateStocks(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)
if(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 = "[pick(CONSONANTS)][pick(VOWELS)]E"
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()
2 changes: 1 addition & 1 deletion code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ SUBSYSTEM_DEF(shuttle)
//supply shuttle stuff
var/obj/docking_port/mobile/supply/supply
var/ordernum = 1 //order number given to next order
var/points = 5000 //number of trade-points we have
var/points = 500 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies

Expand Down
115 changes: 115 additions & 0 deletions code/modules/stock_market/articles.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* This is the code that generates the articles
* that tell you that your stock has plummeted.
*/
/proc/ucfirst(S)
return "[uppertext(ascii2text(text2ascii(S, 1)))][copytext(S, 2)]"

/proc/ucfirsts(S)
var/list/L = splittext(S, " ")
var/list/M = list()
for (var/P in L)
M += ucfirst(P)
return jointext(M, " ")

/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", "conglomerate", "enterprise", "venture"), \
"complete" = list("complete", "total", "absolute", "incredible"), \
"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", "clerks"), \
"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/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 District [rand(4,24)] [pick(nouns)]"
if (2)
return "The [pick(timely)] [pick(nouns)]"

/datum/article/proc/generateAuthorName()
switch(rand(1,3))
if (1)
return "[pick(CONSONANTS)]. [pick(GLOB.last_names)]"
if (2)
return "[prob(50) ? pick(GLOB.first_names_male) : pick(GLOB.first_names_female)] [pick(CONSONANTS)].[prob(50) ? "[pick(CONSONANTS)]. " : null] [pick(GLOB.last_names)]"
if (3)
return "[prob(50) ? pick(GLOB.first_names_male) : pick(GLOB.first_names_female)] \"[prob(50) ? pick(GLOB.first_names_male) : pick(GLOB.first_names_female)]\" [pick(GLOB.last_names)]"

/datum/article/proc/formatSpacetime()
var/ticksc = round(ticks/100)
ticksc = ticksc % 100000
var/ticksp = "[ticksc]"
for(var/cycle = 0 to 4)
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(token_string, list/industry_tokens, 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)
Loading
Loading