From 1352bbbb882e3f44b92ee0e4b6c09ee5ef45be18 Mon Sep 17 00:00:00 2001
From: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Date: Thu, 20 Aug 2020 11:47:43 -0400
Subject: [PATCH] Arconomy Balance Pass 2: Market Tendency (#52974)
Price inflation is now based upon averages, and is now uncapped from 5.
Civilian budget is no longer the worst budget to pay out from.
Medical Civilian bounties are no longer chees-able in seconds.
* I'll pick this up later because it's going to need a UI with keyed lists
* Updated market crash and average inflation values.
* Alright, I'm confident now.
* Make the market crash end at the beginning of the event end
* And on the 2nd day, the lord spoke, "Compile"
* Division by zero protection.
* That should have been a max, smhing my smhead
---
code/__DEFINES/economy.dm | 2 +-
code/controllers/subsystem/economy.dm | 46 ++++++++++++++----------
code/game/machinery/civilian_bounties.dm | 1 +
code/game/machinery/newscaster.dm | 14 ++++----
code/game/objects/items/crab17.dm | 2 ++
code/modules/cargo/bounties/medical.dm | 32 ++++++++++++-----
code/modules/cargo/bounty.dm | 2 +-
code/modules/events/market_crash.dm | 7 ++--
code/modules/vending/_vending.dm | 4 +--
9 files changed, 71 insertions(+), 39 deletions(-)
diff --git a/code/__DEFINES/economy.dm b/code/__DEFINES/economy.dm
index 24fd0bfd800..470d6199f75 100644
--- a/code/__DEFINES/economy.dm
+++ b/code/__DEFINES/economy.dm
@@ -10,7 +10,7 @@
#define PAYCHECK_HARD 100
#define PAYCHECK_COMMAND 200
-#define STATION_TARGET_INCREMENT 150
+#define STATION_TARGET_BUFFER 40
#define MAX_GRANT_CIV 2500
#define MAX_GRANT_ENG 3000
diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm
index 69f9ff6608c..142b011333d 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -51,10 +51,15 @@ SUBSYSTEM_DEF(economy)
var/station_total = 0
/// A var that tracks how much money is expected to be on station at a given time. If less than station_total prices go up in vendors.
var/station_target = 1
+ /// A passively increasing buffer to help alliviate inflation later into the shift, but to a lesser degree.
+ var/station_target_buffer = 0
/// A var that displays the result of inflation_value for easier debugging and tracking.
var/inflation_value = 1
+ /// How many civilain bounties have been completed so far this shift? Affects civilian budget payout values.
+ var/civ_bounty_tracker = 0
/// Contains the message to send to newscasters about price inflation and earnings, updated on price_update()
var/earning_report
+ var/market_crashing = FALSE
/datum/controller/subsystem/economy/Initialize(timeofday)
var/budget_to_hand_out = round(budget_pool / department_accounts.len)
@@ -63,19 +68,24 @@ SUBSYSTEM_DEF(economy)
return ..()
/datum/controller/subsystem/economy/fire(resumed = 0)
+ var/temporary_total = 0
eng_payout() // Payout based on nothing. What will replace it? Surplus power, powered APC's, air alarms? Who knows.
sci_payout() // Payout based on slimes.
secmedsrv_payout() // Payout based on crew safety, health, and mood.
- civ_payout() // Payout based on ??? Profit
+ civ_payout() // Payout based on Effort and market ebb/flow.
car_payout() // Cargo's natural gain in the cash moneys.
station_total = 0
- for(var/A in bank_accounts)
- var/datum/bank_account/B = A
- B.payday(1)
- if(!istype(B, /datum/bank_account/department))
- station_total += B.account_balance
- station_target += (STATION_TARGET_INCREMENT - generated_accounts.len) //More generous the less crew there are.
- price_update()
+ station_target_buffer += STATION_TARGET_BUFFER
+ for(var/account in bank_accounts)
+ var/datum/bank_account/bank_account = account
+ bank_account.payday(1)
+ if(bank_account && bank_account.account_job)
+ temporary_total += (bank_account.account_job.paycheck * STARTING_PAYCHECKS)
+ if(!istype(bank_account, /datum/bank_account/department))
+ station_total += bank_account.account_balance
+ station_target = max(round(temporary_total / max(bank_accounts.len * 2, 1)) + station_target_buffer, 1)
+ if(!market_crashing)
+ price_update()
/datum/controller/subsystem/economy/proc/get_dep_account(dep_id)
for(var/datum/bank_account/department/D in generated_accounts)
@@ -145,7 +155,7 @@ SUBSYSTEM_DEF(economy)
D.adjust_money(min(science_bounty, MAX_GRANT_SCI))
/datum/controller/subsystem/economy/proc/civ_payout()
- var/civ_cash = (rand(1,5) * 500)
+ var/civ_cash = ((rand(1,5) + civ_bounty_tracker) * 500)
var/datum/bank_account/D = get_dep_account(ACCOUNT_CIV)
if(D)
D.adjust_money(min(civ_cash, MAX_GRANT_CIV))
@@ -163,18 +173,18 @@ SUBSYSTEM_DEF(economy)
if(!is_station_level(V.z))
continue
V.reset_prices(V.product_records, V.coin_records)
- earning_report = "Sector Economic Report
Sector price inflation is currently at [SSeconomy.inflation_value()*100]%.
The station budget is currently [station_total] Credits, and the station's targeted allowance is at [station_target] Credits.
That's all from the Nanotrasen Economist Division."
- GLOB.news_network.SubmitArticle(earning_report, "Station Earnings Report", "Station Announcements", null)
+ earning_report = "Sector Economic Report
Sector vendor prices is currently at [SSeconomy.inflation_value()*100]%.
The station spending power is currently [station_total] Credits, and the crew's targeted allowance is at [station_target] Credits.
That's all from the Nanotrasen Economist Division."
+ GLOB.news_network.SubmitArticle(earning_report, "Station Earnings Report", "Station Announcements", null, update_alert = FALSE)
/**
- * Proc that returns a value meant to undercut the value of civilian bounties, based on how much money exists on the station.
+ * Proc that returns a value meant to shift inflation values in vendors, based on how much money exists on the station.
*
* If crew are somehow aquiring far too much money, this value will dynamically cause vendables across the station to skyrocket in price until some money is spent.
+ * Additionally, civilain bounties will cost less, and cargo goodies will increase in price as well.
+ * The goal here is that if you want to spend money, you'll have to get it, and the most efficient method is typically from other players.
**/
/datum/controller/subsystem/economy/proc/inflation_value()
- if(station_total > station_target)
- var/holder = station_total - station_target
- holder = clamp(round((holder / max(station_target,1) + 1),0.1),1,5)
- inflation_value = holder
- return holder
- return 1
+ if(!bank_accounts.len)
+ return 1
+ inflation_value = max(round(((station_total / bank_accounts.len) / station_target), 0.1), 1.0)
+ return inflation_value
diff --git a/code/game/machinery/civilian_bounties.dm b/code/game/machinery/civilian_bounties.dm
index 520bffb8de8..6666058adb3 100644
--- a/code/game/machinery/civilian_bounties.dm
+++ b/code/game/machinery/civilian_bounties.dm
@@ -103,6 +103,7 @@
inserted_scan_id.registered_account.transfer_money(dept_account, curr_bounty.reward)
status_report += "Bounty Completed! [curr_bounty.reward] credits have been paid out. "
inserted_scan_id.registered_account.reset_bounty()
+ SSeconomy.civ_bounty_tracker++
pad.visible_message("[pad] activates!")
flick(pad.sending_state,pad)
pad.icon_state = pad.idle_state
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 800878aab48..cff766b7cb3 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(allCasters)
newChannel.is_admin_channel = adminChannel
network_channels += newChannel
-/datum/newscaster/feed_network/proc/SubmitArticle(msg, author, channel_name, datum/picture/picture, adminMessage = 0, allow_comments = 1)
+/datum/newscaster/feed_network/proc/SubmitArticle(msg, author, channel_name, datum/picture/picture, adminMessage = 0, allow_comments = 1, update_alert = TRUE)
var/datum/newscaster/feed_message/newMsg = new /datum/newscaster/feed_message
newMsg.author = author
newMsg.body = msg
@@ -134,7 +134,7 @@ GLOBAL_LIST_EMPTY(allCasters)
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
- NEWSCASTER.newsAlert(channel_name)
+ NEWSCASTER.newsAlert(channel_name, update_alert)
lastAction ++
newMsg.creationTime = lastAction
@@ -840,14 +840,16 @@ GLOBAL_LIST_EMPTY(allCasters)
alert = FALSE
update_icon()
-/obj/machinery/newscaster/proc/newsAlert(channel)
+/obj/machinery/newscaster/proc/newsAlert(channel, update_alert = TRUE)
if(channel)
- say("Breaking news from [channel]!")
+ if(update_alert)
+ say("Breaking news from [channel]!")
+ playsound(loc, 'sound/machines/twobeep_high.ogg', 75, TRUE)
alert = TRUE
update_icon()
addtimer(CALLBACK(src,.proc/remove_alert),alert_delay,TIMER_UNIQUE|TIMER_OVERRIDE)
- playsound(loc, 'sound/machines/twobeep_high.ogg', 75, TRUE)
- else
+
+ else if(!channel && update_alert)
say("Attention! Wanted issue distributed!")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm
index aac3b5446cd..ea601b0be24 100644
--- a/code/game/objects/items/crab17.dm
+++ b/code/game/objects/items/crab17.dm
@@ -86,6 +86,7 @@
add_overlay("legs_retracted")
addtimer(CALLBACK(src, .proc/startUp), 50)
QDEL_IN(src, 8 MINUTES) //Self-destruct after 8 min
+ SSeconomy.market_crashing = TRUE
/obj/structure/checkoutmachine/proc/startUp() //very VERY snowflake code that adds a neat animation when the pod lands.
@@ -156,6 +157,7 @@
STOP_PROCESSING(SSfastprocess, src)
priority_announce("The credit deposit machine at [get_area(src)] has been destroyed. Station funds have stopped draining!", sender_override = "CRAB-17 Protocol")
explosion(src, 0,0,1, flame_range = 2)
+ SSeconomy.market_crashing = FALSE
return ..()
/obj/structure/checkoutmachine/proc/start_dumping()
diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm
index 3f737448a5b..ceb18dd5814 100644
--- a/code/modules/cargo/bounties/medical.dm
+++ b/code/modules/cargo/bounties/medical.dm
@@ -1,35 +1,39 @@
/datum/bounty/item/medical/heart
name = "Heart"
- description = "Commander Johnson is in critical condition after suffering yet another heart attack. Doctors say he needs a new heart fast. Ship one, pronto!"
+ description = "Commander Johnson is in critical condition after suffering yet another heart attack. Doctors say he needs a new heart fast. Ship one, pronto! We'll take a better cybernetic one, if need be."
reward = 3000
- wanted_types = list(/obj/item/organ/heart)
+ wanted_types = list(/obj/item/organ/heart, /obj/item/organ/heart/cybernetic/tier2, /obj/item/organ/heart/cybernetic/tier3)
+ exclude_types = list(/obj/item/organ/heart/cybernetic)//Excluding tier 1s, no cheesing.
/datum/bounty/item/medical/lung
name = "Lungs"
- description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded."
+ description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded. We'll take a better cybernetic one, if need be."
reward = 10000
required_count = 3
- wanted_types = list(/obj/item/organ/lungs)
+ wanted_types = list(/obj/item/organ/lungs, /obj/item/organ/lungs/cybernetic/tier2, /obj/item/organ/lungs/cybernetic/tier3)
+ exclude_types = list(/obj/item/organ/lungs/cybernetic)//As above, for all printable organs.
/datum/bounty/item/medical/appendix
name = "Appendix"
- description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay."
+ description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay. We'll take a better cybernetic one, if need be."
reward = 5000 //there are no synthetic appendixes
wanted_types = list(/obj/item/organ/appendix)
/datum/bounty/item/medical/ears
name = "Ears"
- description = "Multiple staff at Station 12 have been left deaf due to unauthorized clowning. Ship them new ears."
+ description = "Multiple staff at Station 12 have been left deaf due to unauthorized clowning. Ship them new ears. "
reward = 10000
required_count = 3
- wanted_types = list(/obj/item/organ/ears)
+ wanted_types = list(/obj/item/organ/ears, /obj/item/organ/ears/cybernetic/upgraded)
+ exclude_types = list(/obj/item/organ/ears/cybernetic)
/datum/bounty/item/medical/liver
name = "Livers"
description = "Multiple high-ranking CentCom diplomats have been hospitalized with liver failure after a recent meeting with Third Soviet Union ambassadors. Help us out, will you?"
reward = 10000
required_count = 3
- wanted_types = list(/obj/item/organ/liver)
+ wanted_types = list(/obj/item/organ/liver, /obj/item/organ/liver/cybernetic/tier2, /obj/item/organ/liver/cybernetic/tier3)
+ exclude_types = list(/obj/item/organ/liver/cybernetic)
/datum/bounty/item/medical/eye
name = "Organic Eyes"
@@ -69,3 +73,15 @@
description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails."
reward = 4000
wanted_types = list(/obj/item/melee/chainofcommand/tailwhip)
+
+/datum/bounty/item/medical/surgerycomp
+ name = "Surgery Computer"
+ description = "After another freak bombing incident at our annual cheesefest at centcom, we have a massive stack of injured crew on our end. Please send us a fresh surgery computer, if at all possible."
+ reward = 6000
+ wanted_types = list(/obj/machinery/computer/operating)
+
+/datum/bounty/item/medical/surgerytable
+ name = "Operating Table"
+ description = "After a recent influx of infected crew members recently, we've seen that masks just aren't cutting it alone. Silver Operating tables might just do the trick though, send us one to use."
+ reward = 3000
+ wanted_types = list(/obj/structure/table/optable)
diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm
index 214e875d2ca..a883d68f865 100644
--- a/code/modules/cargo/bounty.dm
+++ b/code/modules/cargo/bounty.dm
@@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
if(guided)
bounty_num = guided
else
- bounty_num = rand(1,13)
+ bounty_num = rand(1,12)
switch(bounty_num)
if(1)
var/subtype = pick(subtypesof(/datum/bounty/item/assistant))
diff --git a/code/modules/events/market_crash.dm b/code/modules/events/market_crash.dm
index 18548e27504..a2e763ea8b2 100644
--- a/code/modules/events/market_crash.dm
+++ b/code/modules/events/market_crash.dm
@@ -25,19 +25,20 @@
var/reason = pick(poss_reasons)
priority_announce("Due to [reason], prices for on-station vendors will be increased for a short period.", "Nanotrasen Accounting Division")
-///This does not work and I could use some help morking this one out further.
/datum/round_event/market_crash/start()
. = ..()
var/num_accounts = 0
for(var/A in SSeconomy.bank_accounts)
num_accounts += 1
market_dip = rand(1000,10000) * num_accounts
- SSeconomy.station_target -= market_dip
- SSeconomy.station_target = max(SSeconomy.station_target, 1)
+ SSeconomy.station_target = max(SSeconomy.station_target - market_dip, 1)
SSeconomy.price_update()
+ SSeconomy.market_crashing = TRUE
/datum/round_event/market_crash/end()
. = ..()
SSeconomy.station_target += market_dip
+ SSeconomy.market_crashing = FALSE
SSeconomy.price_update()
priority_announce("Prices for on-station vendors have now stabilized.", "Nanotrasen Accounting Division")
+
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index fa4c2f20f77..1e7f110cf7b 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -318,8 +318,8 @@ GLOBAL_LIST_EMPTY(vending_products)
if(!start_empty)
R.amount = amount
R.max_amount = amount
- R.custom_price = initial(temp.custom_price) * SSeconomy.inflation_value()
- R.custom_premium_price = initial(temp.custom_premium_price) * SSeconomy.inflation_value()
+ R.custom_price = round(initial(temp.custom_price) * SSeconomy.inflation_value())
+ R.custom_premium_price = round(initial(temp.custom_premium_price) * SSeconomy.inflation_value())
R.age_restricted = initial(temp.age_restricted)
recordlist += R