diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm index 1cc508d8237..b7e75307d64 100644 --- a/code/controllers/subsystems/job.dm +++ b/code/controllers/subsystems/job.dm @@ -332,38 +332,8 @@ if(!megavend) //Equip custom gear loadout. job.equip_backpack(H) job.setup_account(H) - if(H.client.prefs.gear && H.client.prefs.gear.len && job.title != "Cyborg" && job.title != "AI") - for(var/thing in H.client.prefs.gear) - var/datum/gear/G = gear_datums[thing] - if(G) - var/permitted - if(G.allowed_roles) - for(var/job_name in G.allowed_roles) - if(job.title == job_name) - permitted = TRUE - else - permitted = TRUE - if(G.whitelisted && !is_alien_whitelisted(H, all_species[G.whitelisted])) - permitted = FALSE - - if(!permitted) - H << "Your current job or whitelist status does not permit you to spawn with [thing]!" - continue - - if(G.slot && !(G.slot in custom_equip_slots)) - // This is a miserable way to fix the loadout overwrite bug, but the alternative requires - // adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z - var/metadata = H.client.prefs.gear[G.display_name] - if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head) - custom_equip_leftovers += thing - else if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot)) - H << "Equipping you with \the [thing]!" - custom_equip_slots.Add(G.slot) - else - custom_equip_leftovers.Add(thing) - else - spawn_in_storage += thing + EquipCustom(H, job, H.client.prefs, custom_equip_leftovers, spawn_in_storage, custom_equip_slots) // This goes after custom loadout it doesn't prevent custom loadout stuff from being equipped. job.equip_survival(H) @@ -374,18 +344,7 @@ // Randomize nutrition. Defines are in __defines/mobs.dm H.nutrition = (rand(CREW_MINIMUM_NUTRITION, CREW_MAXIMUM_NUTRITION) * 0.01) * H.max_nutrition - //If some custom items could not be equipped before, try again now. - for(var/thing in custom_equip_leftovers) - var/datum/gear/G = gear_datums[thing] - if(G.slot in custom_equip_slots) - spawn_in_storage += thing - else - var/metadata = H.client.prefs.gear[G.display_name] - if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot)) - H << "Equipping you with \the [thing]!" - custom_equip_slots.Add(G.slot) - else - spawn_in_storage += thing + EquipCustomDeferred(H, H.client.prefs, custom_equip_leftovers, custom_equip_slots) else H << "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator." @@ -437,20 +396,8 @@ captain_announcement.Announce("All hands, Captain [H.real_name] on deck!", new_sound=announce_sound) //Deferred item spawning. - if(spawn_in_storage && spawn_in_storage.len) - var/obj/item/weapon/storage/B - for(var/obj/item/weapon/storage/S in H.contents) - B = S - break - - if(B) - for(var/thing in spawn_in_storage) - H << "Placing \the [thing] in your [B.name]!" - var/datum/gear/G = gear_datums[thing] - var/metadata = H.client.prefs.gear[G.display_name] - G.spawn_item(B, metadata) - else - H << "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug." + if(LAZYLEN(spawn_in_storage)) + EquipItemsStorage(H, H.client.prefs, spawn_in_storage) if(istype(H) && !megavend) //give humans wheelchairs, if they need them. var/obj/item/organ/external/l_foot = H.get_organ("l_foot") @@ -534,82 +481,26 @@ //Equip custom gear loadout. var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage. var/list/custom_equip_leftovers = list() - if(LAZYLEN(H.client.prefs.gear) && job.title != "Cyborg" && job.title != "AI") - for(var/thing in H.client.prefs.gear) - var/datum/gear/G = gear_datums[thing] - if(G) - var/permitted - if(G.allowed_roles) - for(var/job_name in G.allowed_roles) - if(job.title == job_name) - permitted = TRUE - break - else - permitted = TRUE - if(G.whitelisted && !is_alien_whitelisted(H, all_species[G.whitelisted])) - permitted = FALSE - - if(!permitted) - H << "Your current job or whitelist status does not permit you to spawn with [thing]!" - continue - - if(G.slot && !(G.slot in custom_equip_slots)) - // This is a miserable way to fix the loadout overwrite bug, but the alternative requires - // adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z - var/metadata = H.client.prefs.gear[G.display_name] - var/obj/item/CI = G.spawn_item(H,metadata) - if (G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head) - custom_equip_leftovers += thing - else if (H.equip_to_slot_or_del(CI, G.slot)) - CI.autodrobe_no_remove = TRUE - H << "Equipping you with \the [thing]!" - custom_equip_slots += G.slot - else - custom_equip_leftovers += thing - else - spawn_in_storage += thing + EquipCustom(H, job, H.client.prefs, custom_equip_leftovers, spawn_in_storage, custom_equip_slots) //Equip job items. job.late_equip(H) job.equip_backpack(H) job.equip_survival(H) job.setup_account(H) + + EquipCustomDeferred(H, H.client.prefs, custom_equip_leftovers, custom_equip_slots) + job.apply_fingerprints(H) - //If some custom items could not be equipped before, try again now. - for(var/thing in custom_equip_leftovers) - var/datum/gear/G = gear_datums[thing] - if(G.slot in custom_equip_slots) - spawn_in_storage += thing - else - var/metadata = H.client.prefs.gear[G.display_name] - var/obj/item/CI = G.spawn_item(H,metadata) - if(H.equip_to_slot_or_del(CI, G.slot)) - H << "Equipping you with \the [thing]!" - custom_equip_slots += G.slot - CI.autodrobe_no_remove = TRUE - else - spawn_in_storage += thing else H << "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator." H.job = rank if(LAZYLEN(spawn_in_storage)) - var/obj/item/weapon/storage/B - for(var/obj/item/weapon/storage/S in H.contents) - B = S - break - - if(B) - for(var/thing in spawn_in_storage) - H << "Placing \the [thing] in your [B.name]!" - var/datum/gear/G = gear_datums[thing] - var/metadata = H.client.prefs.gear[G.display_name] - G.spawn_item(B, metadata) - else - H << "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug." + EquipItemsStorage(H, H.client.prefs, spawn_in_storage) if(istype(H)) //give humans wheelchairs, if they need them. var/obj/item/organ/external/l_foot = H.get_organ("l_foot") @@ -805,3 +696,90 @@ // Delete the mob. qdel(H) + +// Equips a human-type with their custom loadout crap. +// Returns TRUE on success, FALSE otherwise. +// H, job, and prefs MUST be supplied and not null. +// leftovers, storage, custom_equip_slots can be passed if their return values are required (proc mutates passed list), or ignored if not required. +/datum/controller/subsystem/jobs/proc/EquipCustom(mob/living/carbon/human/H, datum/job/job, datum/preferences/prefs, list/leftovers = null, list/storage = null, list/custom_equip_slots = list()) + if (!istype(H) || !job) + return FALSE + + switch (job.title) + if ("AI", "Cyborg") + return FALSE + + for(var/thing in prefs.gear) + var/datum/gear/G = gear_datums[thing] + if(G) + var/permitted + if(G.allowed_roles) + for(var/job_name in G.allowed_roles) + if(job.title == job_name) + permitted = TRUE + break + else + permitted = TRUE + + if(G.whitelisted && !is_alien_whitelisted(H, all_species[G.whitelisted])) + permitted = FALSE + + if(!permitted) + H << "Your current job or whitelist status does not permit you to spawn with [thing]!" + continue + + if(G.slot && !(G.slot in custom_equip_slots)) + // This is a miserable way to fix the loadout overwrite bug, but the alternative requires + // adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z + var/metadata = prefs.gear[G.display_name] + var/obj/item/CI = G.spawn_item(H,metadata) + if (G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head) + if (leftovers) + leftovers += thing + else if (H.equip_to_slot_or_del(CI, G.slot)) + CI.autodrobe_no_remove = TRUE + H << "Equipping you with \a [thing]!" + custom_equip_slots += G.slot + else if (leftovers) + leftovers += thing + else if (storage) + storage += thing + + return TRUE + +// Attempts to equip custom items that failed to equip in EquipCustom. +// Returns a list of items that failed to equip & should be put in storage if possible. +// H and prefs must not be null. +/datum/controller/subsystem/jobs/proc/EquipCustomDeferred(mob/living/carbon/human/H, datum/preferences/prefs, list/items, list/used_slots) + . = list() + for (var/thing in items) + var/datum/gear/G = gear_datums[thing] + + if (G.slot in used_slots) + . += thing + else + var/metadata = prefs.gear[G.display_name] + var/obj/item/CI = G.spawn_item(H, metadata) + if (H.equip_to_slot_or_del(CI, G.slot)) + to_chat(H, "Equipping you with \a [thing]!") + used_slots += G.slot + CI.autodrobe_no_remove = TRUE + + else + . += thing + +// Attempts to place everything in items into a storage object located on H, deleting them if they're unable to be inserted. +// H and prefs must not be null. +// Returns nothing. +/datum/controller/subsystem/jobs/proc/EquipItemsStorage(mob/living/carbon/human/H, datum/preferences/prefs, list/items) + if (LAZYLEN(items)) + var/obj/item/weapon/storage/B = locate() in H + if (B) + for (var/thing in items) + to_chat(H, "Placing \the [thing] in your [B.name]!") + var/datum/gear/G = gear_datums[thing] + var/metadata = prefs.gear[G.display_name] + G.spawn_item(B, metadata) + + else + to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.") diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index eef302f55f4..0b26debe1fe 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -216,29 +216,16 @@ datum/preferences if(previewJob) mannequin.job = previewJob.title + + var/list/leftovers = list() + var/list/used_slots = list() + + SSjobs.EquipCustom(mannequin, previewJob, src, leftovers, null, used_slots) + previewJob.equip_preview(mannequin, player_alt_titles[previewJob.title]) - var/list/equipped_slots = list() //If more than one item takes the same slot only spawn the first - for(var/thing in gear) - var/datum/gear/G = gear_datums[thing] - if(G) - var/permitted = 0 - if(G.allowed_roles) - for(var/job_name in G.allowed_roles) - if(previewJob.title == job_name) - permitted = 1 - else - permitted = 1 - if(G.whitelisted && (G.whitelisted != mannequin.species.name)) - permitted = 0 + SSjobs.EquipCustomDeferred(mannequin, src, leftovers, used_slots) - if(!permitted) - continue - - if(G.slot && !(G.slot in equipped_slots)) - equipped_slots += G.slot - var/metadata = gear[G.display_name] - mannequin.equip_to_slot_or_del(G.spawn_item(mannequin, metadata), G.slot) mannequin.update_icons() /datum/preferences/proc/update_preview_icon()