diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 6d77a1f6..8db1eb12 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(job)
var/overflow_role = "Assistant"
+
/datum/controller/subsystem/job/Initialize(timeofday)
SSmapping.HACK_LoadMapConfig()
if(!occupations.len)
@@ -390,7 +391,6 @@ SUBSYSTEM_DEF(job)
var/datum/job/job = GetJob(rank)
H.job = rank
- equip_loadout(N, H)
//If we joined at roundstart we should be positioned at our workstation
if(!joined_late)
@@ -416,22 +416,36 @@ SUBSYSTEM_DEF(job)
if(H.mind)
H.mind.assigned_role = rank
+ //Job loadout, equipping, and flavortext when spawning
if(job)
- var/new_mob = job.equip(H, null, null, joined_late)
- if(ismob(new_mob))
+ var/list/handle_storage = equip_loadout(N, H) //Loadout gear
+ var/new_mob = job.equip(H, null, null, joined_late) //Job gear
+
+ if(ismob(new_mob)) //The above doesnt return a value, but we check this anyways or else everything breaks!
H = new_mob
if(!joined_late)
N.new_character = H
else
M = H
- SSpersistence.antag_rep_change[M.client.ckey] += job.GetAntagRep()
+ if(LAZYLEN(handle_storage)) //equip_loadout returned a list. This list is backpack contents we should store, as by now we should have a backpack and a single reference mob
+ if(ishuman(H))
+ var/mob/living/carbon/human/_H = H
+ if(_H.back)
+ for(var/atom/movable/A in handle_storage)
+ if(!SEND_SIGNAL(_H.back, COMSIG_TRY_STORAGE_INSERT, A, null, TRUE, TRUE))
+ A.forceMove(get_turf(H)) //Try and store into the backpack. If the backpack is full, drop it to the ground
+ else //No backpack
+ for(var/atom/movable/A in handle_storage)
+ A.forceMove(get_turf(H))
+
+ //Flavortext
+ var/display_rank = rank
+ if(M.client && M.client.prefs && M.client.prefs.alt_titles_preferences[rank])
+ display_rank = M.client.prefs.alt_titles_preferences[rank]
+
+ to_chat(M, "You are the [display_rank].")
- var/display_rank = rank
- if(M.client && M.client.prefs && M.client.prefs.alt_titles_preferences[rank])
- display_rank = M.client.prefs.alt_titles_preferences[rank]
- to_chat(M, "You are the [display_rank].")
- if(job)
to_chat(M, "As the [display_rank] you answer directly to [job.supervisors]. Special circumstances may change this.")
to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset.")
if(job.req_admin_notify)
@@ -440,16 +454,14 @@ SUBSYSTEM_DEF(job)
to_chat(M, "[job.custom_spawn_text]")
if(CONFIG_GET(number/minimal_access_threshold))
to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.")
-
+
+ //Account ID. ID is handled by human initialization
if(ishuman(H))
var/mob/living/carbon/human/wageslave = H
- to_chat(M, "Your account ID is [wageslave.account_id]")
- to_chat(M, "You do not have a pin, can set your pin at a ATM.")
- H.add_memory("Your account ID is [wageslave.account_id].")
-
- if(job && H)
- job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
- equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
+ to_chat(M, "Your account ID is [wageslave.account_id]")
+ to_chat(M, "You do not have a pin, can set your pin at an ATM.")
+ if(H.mind)
+ H.mind.memory += "Your account ID is [wageslave.account_id].
"
return H
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
index 2cd30da8..3dfe7153 100644
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -39,52 +39,49 @@
pre_equip(H, visualsOnly)
//Start with uniform,suit,backpack for additional slots
- if(uniform)
- H.equip_to_slot_or_store_and_del(new uniform(H),SLOT_W_UNIFORM)
- if(suit)
- H.equip_to_slot_or_store_and_del(new suit(H),SLOT_WEAR_SUIT)
if(back)
H.equip_to_slot_or_del(new back(H),SLOT_BACK)
-
- if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
- if(l_pocket)
- H.equip_to_slot_or_store_and_del(new l_pocket(H),SLOT_L_STORE)
- if(r_pocket)
- H.equip_to_slot_or_store_and_del(new r_pocket(H),SLOT_R_STORE)
- if(backpack_contents)
+ if(!visualsOnly && backpack_contents) //Keep things organized when we can't equip other stuff by having this first
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
- if(belt)
- H.equip_to_slot_or_store_and_del(new belt(H),SLOT_BELT)
- if(gloves)
- H.equip_to_slot_or_store_and_del(new gloves(H),SLOT_GLOVES)
- if(shoes)
- H.equip_to_slot_or_store_and_del(new shoes(H),SLOT_SHOES)
- if(head)
- H.equip_to_slot_or_store_and_del(new head(H),SLOT_HEAD)
- if(mask)
- H.equip_to_slot_or_store_and_del(new mask(H),SLOT_WEAR_MASK)
- if(neck)
- H.equip_to_slot_or_store_and_del(new neck(H),SLOT_NECK)
- if(ears)
- H.equip_to_slot_or_store_and_del(new ears(H),SLOT_EARS)
- if(glasses)
- H.equip_to_slot_or_store_and_del(new glasses(H),SLOT_GLASSES)
- if(id)
- H.equip_to_slot_or_store_and_del(new id(H),SLOT_WEAR_ID)
- if(suit_store)
- H.equip_to_slot_or_store_and_del(new suit_store(H),SLOT_S_STORE)
-
- if(accessory)
- var/obj/item/clothing/under/U = H.w_uniform
- if(U)
+
+ if(uniform)
+ var/obj/item/clothing/under/U = new uniform(H)
+ H.equip_to_slot_or_store(U,SLOT_W_UNIFORM)
+ if(accessory)
U.attach_accessory(new accessory(H))
- else
- WARNING("Unable to equip accessory [accessory] in outfit [name]. No uniform present!")
+ if(suit)
+ H.equip_to_slot_or_store(new suit(H),SLOT_WEAR_SUIT)
+
+ if(!visualsOnly)
+ if(l_pocket)
+ H.equip_to_slot_or_store(new l_pocket(H),SLOT_L_STORE)
+ if(r_pocket)
+ H.equip_to_slot_or_store(new r_pocket(H),SLOT_R_STORE)
+ if(belt)
+ H.equip_to_slot_or_store(new belt(H),SLOT_BELT)
+ if(gloves)
+ H.equip_to_slot_or_store(new gloves(H),SLOT_GLOVES)
+ if(shoes)
+ H.equip_to_slot_or_store(new shoes(H),SLOT_SHOES)
+ if(head)
+ H.equip_to_slot_or_store(new head(H),SLOT_HEAD)
+ if(mask)
+ H.equip_to_slot_or_store(new mask(H),SLOT_WEAR_MASK)
+ if(neck)
+ H.equip_to_slot_or_store(new neck(H),SLOT_NECK)
+ if(ears)
+ H.equip_to_slot_or_store(new ears(H),SLOT_EARS)
+ if(glasses)
+ H.equip_to_slot_or_store(new glasses(H),SLOT_GLASSES)
+ if(id)
+ H.equip_to_slot_or_store(new id(H),SLOT_WEAR_ID)
+ if(suit_store)
+ H.equip_to_slot_or_store(new suit_store(H),SLOT_S_STORE)
if(l_hand)
H.put_in_l_hand(new l_hand(H))
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 04314dd7..6faf5465 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -36,7 +36,7 @@
var/buckle_message_cooldown = 0
var/fingerprintslast
- var/list/filter_data //For handling persistent filters
+ var/list/filter_data = list() //For handling persistent filters
var/datum/component/orbiter/orbiters
@@ -861,14 +861,16 @@ Proc for attack log creation, because really why not
filters += filter(arglist(arguments))
/atom/movable/proc/get_filter(name)
- if(filter_data && filter_data[name])
- return filters[filter_data.Find(name)]
+ if(filter_data)
+ if(filter_data[name])
+ return filters[filter_data.Find(name)]
/atom/movable/proc/remove_filter(name)
- if(filter_data[name])
- filter_data -= name
- update_filters()
- return TRUE
+ if(filter_data)
+ if(filter_data[name])
+ filter_data -= name
+ update_filters()
+ return TRUE
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
diff --git a/code/modules/hydroponics/grown/peas.dm b/code/modules/hydroponics/grown/peas.dm
index da5f57ce..b17ab329 100644
--- a/code/modules/hydroponics/grown/peas.dm
+++ b/code/modules/hydroponics/grown/peas.dm
@@ -29,13 +29,13 @@
distill_reagent = /datum/reagent/saltpetre
-// Laughin' Peas
+// Laughing Peas
/obj/item/seeds/peas/laugh
- name = "pack of laughin' peas"
- desc = "These seeds give off a very soft purple glow.. they should grow into Laughin' Peas."
+ name = "pack of laughing peas"
+ desc = "These seeds give off a very soft purple glow.. they should grow into Laughing Peas."
icon_state = "seed-laughpeas"
species = "laughpeas"
- plantname = "Laughin' Peas"
+ plantname = "Laughing Peas"
product = /obj/item/reagent_containers/food/snacks/grown/laugh
maturation = 7
potency = 10
@@ -53,7 +53,7 @@
/obj/item/reagent_containers/food/snacks/grown/laugh
seed = /obj/item/seeds/peas/laugh
- name = "pod of laughin' peas"
+ name = "pod of laughing peas"
desc = "Ridens Cicer, guaranteed to improve your mood dramatically upon consumption!"
icon_state = "laughpeas"
filling_color = "#ee7bee"
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index 592c3640..4b76393a 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -29,13 +29,22 @@ Captain
/datum/job/captain/get_access()
return get_all_accesses()
-/datum/job/captain/announce(mob/living/carbon/human/H)
- ..()
- var/displayed_rank = H.client.prefs.alt_titles_preferences[title]
- if(!displayed_rank)
- displayed_rank = "Captain"
- SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!"))
+/datum/job/captain/announce(mob/living/carbon/human/H, tried=FALSE)
+ if(!H)
+ return
+ if(!H.client && !tried) //Roundstart mobs don't have clients when announce() gets called
+ SSticker.OnRoundstart(CALLBACK(src, .proc/announce, H, TRUE)) //So we try again...
+ return
+ if(tried && !H.client) //We don't want to endlessly call ourselves when we don't have a client
+ throw EXCEPTION("[H.nameless ? "Captain" : "Captain [H.real_name]"] ([H.x],[H.y],[H.z]) has no client.")
+ return
+ var/displayed_rank = H.client.prefs.alt_titles_preferences[title]
+ if(!displayed_rank) //Default to Captain
+ displayed_rank = "Captain"
+
+ minor_announce("[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!")
+ ..()
/datum/outfit/job/captain
name = "Captain"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index bca71db9..aed97b00 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -240,10 +240,11 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
return FALSE
if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self))
if(store && istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- var/obj/item/storage/backpack/BP = H.back
- if(BP)
- return SEND_SIGNAL(BP, COMSIG_TRY_STORAGE_INSERT, W, null, TRUE, TRUE)
+ equip_to_slot(W, SLOT_IN_BACKPACK, FALSE)
+ return TRUE
+ else if(store && !qdel_on_fail)
+ W.forceMove(get_turf(src))
+
if(qdel_on_fail)
qdel(W)
else if(!disable_warning)
diff --git a/hyperstation/code/controllers/subsystem/economy.dm b/hyperstation/code/controllers/subsystem/economy.dm
index b69e29c8..282af80e 100644
--- a/hyperstation/code/controllers/subsystem/economy.dm
+++ b/hyperstation/code/controllers/subsystem/economy.dm
@@ -2,8 +2,9 @@ SUBSYSTEM_DEF(economy)
name = "Economy"
wait = 5 MINUTES
init_order = INIT_ORDER_ECONOMY
+ flags = SS_NO_FIRE
runlevels = RUNLEVEL_GAME
var/roundstart_paychecks = 5
var/budget_pool = 35000
var/list/generated_accounts = list()
- var/list/bank_accounts = list() //List of normal accounts (not department accounts)
\ No newline at end of file
+ var/list/bank_accounts = list() //List of normal accounts (not department accounts)
diff --git a/modular_citadel/code/controllers/subsystem/job.dm b/modular_citadel/code/controllers/subsystem/job.dm
index f66cbe81..847ab18e 100644
--- a/modular_citadel/code/controllers/subsystem/job.dm
+++ b/modular_citadel/code/controllers/subsystem/job.dm
@@ -1,39 +1,32 @@
-/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, backpackstuffs)
+/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M)
var/mob/the_mob = N
if(!the_mob)
the_mob = M // cause this doesn't get assigned if player is a latejoiner
- if(the_mob.client && the_mob.client.prefs && (the_mob.client.prefs.chosen_gear && the_mob.client.prefs.chosen_gear.len))
+ if(the_mob.client.prefs)
if(!ishuman(M))//no silicons allowed
return
- for(var/i in the_mob.client.prefs.chosen_gear)
+
+ var/list/queued_to_equip = list() //Items that will equip onto the player
+ . = list() //Items that will be stored into the player's backpack, handled by EquipRank()
+ for(var/i in the_mob.client.prefs.chosen_gear) //Prepare the player's loadout gear
var/datum/gear/G = i
G = GLOB.loadout_items[slot_to_string(initial(G.category))][initial(G.name)]
if(!G)
continue
- if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
- continue
- if(G.ckeywhitelist && G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist))
- continue
-
+ if(G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
+ continue //If the player can't equip this because they lack the required job
+ if(G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist))
+ continue //And you may ask yourself, "Well... How did I get here?"
+
+ if(G.category == SLOT_IN_BACKPACK || G.blacklist_join_equip)
+ . += new G.path
+ else
+ queued_to_equip += G
+
+ for(var/datum/gear/G in queued_to_equip)
var/obj/item/I = new G.path
- if(iscarbon(M) && backpackstuffs && (G.category == SLOT_IN_BACKPACK || G.blacklist_join_equip))
- var/mob/living/carbon/C = M
- var/obj/item/storage/backpack/B = C.back
- if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE))
- I.forceMove(get_turf(C))
- continue
- else if(G.blacklist_join_equip) //Assume we're gonna be put in a backpack and not equipped
- continue
- else if(backpackstuffs && G.category != SLOT_IN_BACKPACK)
- continue
- if(!M.equip_to_slot_if_possible(I, G.category, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- var/obj/item/storage/backpack/B = C.back
- if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE)) // Otherwise, try to put it in the backpack, for carbons.
- I.forceMove(get_turf(C))
- else if(!M.equip_to_slot_if_possible(I, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack
- I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob.
+ if(!M.equip_to_slot_if_possible(I, G.category, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
+ . += I //If the player's unable to equip the item, queue it for storage
/datum/controller/subsystem/job/proc/FreeRole(rank)
if(!rank)
diff --git a/modular_citadel/code/modules/client/loadout/loadout.dm b/modular_citadel/code/modules/client/loadout/loadout.dm
index f184e63a..a02faf6c 100644
--- a/modular_citadel/code/modules/client/loadout/loadout.dm
+++ b/modular_citadel/code/modules/client/loadout/loadout.dm
@@ -50,8 +50,8 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids)
var/path //item-to-spawn path
var/cost = 1 //normally, each loadout costs a single point.
var/geargroupID //defines the ID that the gear inherits from the config
- var/list/restricted_roles
- var/list/ckeywhitelist
+ var/list/restricted_roles = list()
+ var/list/ckeywhitelist = list()
var/restricted_desc
var/blacklist_join_equip = FALSE //If we don't equip this when we join