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)