diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 259d89bef9f..89c343b2616 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -469,10 +469,11 @@
var/station_vault = 0
///How many players joined the round.
var/total_players = GLOB.joined_player_list.len
- for(var/i in SSeconomy.bank_accounts)
- if(istype(i, /datum/bank_account/department) || istype(i, /datum/bank_account/remote))
+ var/list/typecache_bank = typecacheof(list(/datum/bank_account/department, /datum/bank_account/remote))
+ for(var/i in SSeconomy.bank_accounts_by_id)
+ var/datum/bank_account/current_acc = SSeconomy.bank_accounts_by_id[i]
+ if(typecache_bank[current_acc.type])
continue
- var/datum/bank_account/current_acc = i
station_vault += current_acc.account_balance
if(!mr_moneybags || mr_moneybags.account_balance < current_acc.account_balance)
mr_moneybags = current_acc
diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm
index 16f242d2a83..1f23fde6547 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -45,7 +45,11 @@ SUBSYSTEM_DEF(economy)
"adamantine" = 750,
// tier 4
"rainbow" = 1000)
- var/list/bank_accounts = list() //List of normal accounts (not department accounts)
+ /**
+ * List of normal (no department ones) accounts' identifiers with associated datum accounts, for big O performance.
+ * A list of sole account datums can be obtained with flatten_list(), another variable would be redundant rn.
+ */
+ var/list/bank_accounts_by_id = list()
var/list/dep_cards = list()
/// A var that collects the total amount of credits owned in player accounts on station, reset and recounted on fire()
var/station_total = 0
@@ -76,14 +80,14 @@ SUBSYSTEM_DEF(economy)
car_payout() // Cargo's natural gain in the cash moneys.
station_total = 0
station_target_buffer += STATION_TARGET_BUFFER
- for(var/account in bank_accounts)
- var/datum/bank_account/bank_account = account
+ for(var/account in bank_accounts_by_id)
+ var/datum/bank_account/bank_account = bank_accounts_by_id[account]
bank_account.payday(1)
if(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)
+ station_target = max(round(temporary_total / max(bank_accounts_by_id.len * 2, 1)) + station_target_buffer, 1)
if(!market_crashing)
price_update()
@@ -184,7 +188,7 @@ SUBSYSTEM_DEF(economy)
* 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(!bank_accounts.len)
+ if(!bank_accounts_by_id.len)
return 1
- inflation_value = max(round(((station_total / bank_accounts.len) / station_target), 0.1), 1.0)
+ inflation_value = max(round(((station_total / bank_accounts_by_id.len) / station_target), 0.1), 1.0)
return inflation_value
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 0014d9768a0..482991c317c 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -200,17 +200,16 @@
to_chat(user, "The account ID was already assigned to this card.")
return
- for(var/A in SSeconomy.bank_accounts)
- var/datum/bank_account/B = A
- if(B.account_id == new_bank_id)
- if (old_account)
- old_account.bank_cards -= src
+ var/datum/bank_account/B = SSeconomy.bank_accounts_by_id["[new_bank_id]"]
+ if(B)
+ if (old_account)
+ old_account.bank_cards -= src
- B.bank_cards += src
- registered_account = B
- to_chat(user, "The provided account has been linked to this ID card.")
+ B.bank_cards += src
+ registered_account = B
+ to_chat(user, "The provided account has been linked to this ID card.")
- return TRUE
+ return TRUE
to_chat(user, "The account ID number provided is invalid.")
return
@@ -419,12 +418,11 @@ update_label()
if(ishuman(user))
var/mob/living/carbon/human/accountowner = user
- for(var/bank_account in SSeconomy.bank_accounts)
- var/datum/bank_account/account = bank_account
- if(account.account_id == accountowner.account_id)
- account.bank_cards += src
- registered_account = account
- to_chat(user, "Your account number has been automatically assigned.")
+ var/datum/bank_account/account = SSeconomy.bank_accounts_by_id["[accountowner.account_id]"]
+ if(account)
+ account.bank_cards += src
+ registered_account = account
+ to_chat(user, "Your account number has been automatically assigned.")
return
else if (popup_input == "Forge/Reset" && forged)
registered_name = initial(registered_name)
diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm
index 94a199ec2d7..5ccfe8ee854 100644
--- a/code/game/objects/items/crab17.dm
+++ b/code/game/objects/items/crab17.dm
@@ -21,7 +21,7 @@
var/turf/targetturf = get_safe_random_station_turf()
if (!targetturf)
return FALSE
- var/list/accounts_to_rob = SSeconomy.bank_accounts.Copy()
+ var/list/accounts_to_rob = flatten_list(SSeconomy.bank_accounts_by_id)
var/mob/living/carbon/human/H = user
accounts_to_rob -= H.get_bank_account()
for(var/i in accounts_to_rob)
@@ -161,7 +161,7 @@
return ..()
/obj/structure/checkoutmachine/proc/start_dumping()
- accounts_to_rob = SSeconomy.bank_accounts.Copy()
+ accounts_to_rob = flatten_list(SSeconomy.bank_accounts_by_id)
accounts_to_rob -= bogdanoff.get_bank_account()
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
@@ -172,7 +172,8 @@
var/percentage_lost = (rand(5, 15) / 100)
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
- if(!B.being_dumped)
+ if(!(B?.being_dumped))
+ accounts_to_rob -= B
continue
var/amount = B.account_balance * percentage_lost
var/datum/bank_account/account = bogdanoff.get_bank_account()
@@ -189,7 +190,8 @@
/obj/structure/checkoutmachine/proc/stop_dumping()
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
- B.being_dumped = FALSE
+ if(B)
+ B.being_dumped = FALSE
/obj/effect/dumpeet_fall //Falling pod
name = ""
diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm
index 8bb1cb56539..19f4f11aaee 100644
--- a/code/modules/economy/account.dm
+++ b/code/modules/economy/account.dm
@@ -13,18 +13,43 @@
var/bounty_timer = 0
/datum/bank_account/New(newname, job, modifier = 1)
- if(add_to_accounts)
- SSeconomy.bank_accounts += src
account_holder = newname
account_job = job
- account_id = rand(111111,999999)
payday_modifier = modifier
+ setup_unique_account_id()
/datum/bank_account/Destroy()
if(add_to_accounts)
- SSeconomy.bank_accounts -= src
+ SSeconomy.bank_accounts_by_id -= "[account_id]"
return ..()
+/// Proc guarantees the account_id possesses a unique number. If it doesn't, it tries to find a unique alternative. It then adds it to the `SSeconomy.bank_accounts_by_id` global list.
+/datum/bank_account/proc/setup_unique_account_id()
+ if(account_id && !SSeconomy.bank_accounts_by_id["[account_id]"])
+ SSeconomy.bank_accounts_by_id["[account_id]"] = src
+ return //Already unique
+ for(var/i in 1 to 1000)
+ account_id = rand(111111, 999999)
+ if(!SSeconomy.bank_accounts_by_id["[account_id]"])
+ break
+ if(SSeconomy.bank_accounts_by_id["[account_id]"])
+ stack_trace("Unable to find a unique account ID, substituting currently existing account of id [account_id].")
+ SSeconomy.bank_accounts_by_id["[account_id]"] = src
+
+/datum/bank_account/vv_edit_var(var_name, var_value) // just so you don't have to do it manually
+ var/old_id = account_id
+ . = ..()
+ switch(var_name)
+ if(NAMEOF(src, account_id))
+ if(add_to_accounts)
+ SSeconomy.bank_accounts_by_id -= "[old_id]"
+ setup_unique_account_id()
+ if(NAMEOF(src, add_to_accounts))
+ if(add_to_accounts)
+ setup_unique_account_id()
+ else
+ SSeconomy.bank_accounts_by_id -= "[account_id]"
+
/datum/bank_account/proc/dumpeet()
being_dumped = TRUE
diff --git a/code/modules/events/market_crash.dm b/code/modules/events/market_crash.dm
index a2e763ea8b2..8fcf5d44fe4 100644
--- a/code/modules/events/market_crash.dm
+++ b/code/modules/events/market_crash.dm
@@ -27,10 +27,7 @@
/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
+ market_dip = rand(1000,10000) * length(SSeconomy.bank_accounts_by_id)
SSeconomy.station_target = max(SSeconomy.station_target - market_dip, 1)
SSeconomy.price_update()
SSeconomy.market_crashing = TRUE
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 200c47eca93..9f40deadc64 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -243,12 +243,10 @@
if(H.age)
C.registered_age = H.age
C.update_label()
- for(var/A in SSeconomy.bank_accounts)
- var/datum/bank_account/B = A
- if(B.account_id == H.account_id)
- C.registered_account = B
- B.bank_cards += C
- break
+ var/datum/bank_account/B = SSeconomy.bank_accounts_by_id["[H.account_id]"]
+ if(B && B.account_id == H.account_id)
+ C.registered_account = B
+ B.bank_cards += C
H.sec_hud_set_ID()
var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot)