Files

164 lines
6.0 KiB
Plaintext

/datum/preferences/proc/spawn_checks(flags, list/errors, list/warnings)
. = TRUE
for(var/datum/category_group/player_setup_category/category in player_setup.categories)
if(!category.spawn_checks(src, flags, errors, warnings))
. = FALSE
// todo: at some point we should support nonhuman copy to's better.
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, flags)
// Sanitizing rather than saving as someone might still be editing when copy_to occurs.
player_setup.sanitize_setup()
sanitize_everything()
// snowflake begin
// Special Case: This references variables owned by two different datums, so do it here.
if(be_random_name)
real_name = random_name(identifying_gender, real_species_name())
// snowflake end
// Copy start
// Gather
// todo: cache items by load order
var/list/datum/category_item/player_setup_item/items = list()
for(var/datum/category_group/player_setup_category/C as anything in player_setup.categories)
for(var/datum/category_item/player_setup_item/I as anything in C.items)
BINARY_INSERT(I, items, /datum/category_item/player_setup_item, I, load_order, COMPARE_KEY)
// copy to
for(var/datum/category_item/player_setup_item/I as anything in items)
I.copy_to_mob(src, character, I.is_global? get_global_data(I.save_key) : get_character_data(I.save_key), flags)
// Sync up all their organs and species one final time
character.force_update_organs()
// character.s_base = s_base //doesn't work, fuck me
if(!(flags & PREF_COPY_TO_DO_NOT_RENDER))
character.force_update_limbs()
character.update_icons_body()
character.update_mutations()
character.update_underwear()
character.update_hair()
if(LAZYLEN(character.descriptors))
for(var/entry in body_descriptors)
character.descriptors[entry] = body_descriptors[entry]
/**
* /datum/mind is usually used to semantically track someone's soul
* (this sounds stupid to say in a code comment but whatever)
*
* therefore if we want to get original state of a player at roundstart,
* we're going to want to store prefs data
*
* pref items are able to copy_to_mob without a prefs datum to support this
*/
/datum/preferences/proc/imprint_mind(datum/mind/M)
M.original_save_data = deep_copy_list(character)
M.original_pref_economic_modifier = tally_background_economic_factor()
/**
* generates an appearance from our current looks
*/
/datum/preferences/proc/render_to_appearance(flags)
var/mob/living/carbon/human/dummy/mannequin/renderer = generate_or_wait_for_human_dummy("prefs/render_to_appearance")
copy_to(renderer, flags)
if(flags & PREF_COPY_TO_UNRESTRICTED_LOADOUT)
equip_loadout(renderer)
renderer.compile_overlays()
. = renderer.appearance
unset_busy_human_dummy("prefs/render_to_appearance")
/**
* equips loadout
*
* @params
* * character - the mob
* * flags - PREF_COPY_TO_ flags like in [copy_to]
* * role - (optional) the /datum/prototype/role being used.
* * allow_storage_spawn - spawn extra items in storage instead of stuffing into reject.
* * reject - list to stuff rejected items into. if null, they're deleted.
*/
/datum/preferences/proc/equip_loadout(mob/character, flags, datum/prototype/role/role, allow_storage_spawn, list/reject)
//! todo: copypaste, refactor
var/mob/living/carbon/human/H = character
if(!istype(H))
return
//! end
// check allow storage spawns
if(isnull(allow_storage_spawn))
// by default, we only spawn stuff in backpack if they're actually spawning in.
allow_storage_spawn = PREF_COPYING_TO_CHECK_IS_SPAWNING(flags)
// generate gear datum + data list
var/list/loadout = generate_loadout_entry_list(flags, role)
SEND_SIGNAL(character, COMSIG_HUMAN_EQUIPPING_LOADOUT, flags, role, loadout)
// overflow list of items associated to slot IDs
var/list/obj/item/overflow = list()
// first pass
for(var/datum/loadout_entry/entry as anything in loadout)
var/list/data = loadout[entry]
var/obj/item/instanced = entry.instantiate(entry_data = data)
var/use_slot = entry.slot
var/succeeded = FALSE
switch(use_slot)
if("implant")
var/obj/item/implant/implant = instanced
INVOKE_ASYNC(implant, TYPE_PROC_REF(/obj/item/implant, implant_loadout), character)
succeeded = TRUE
if(null)
succeeded = FALSE
else
succeeded = H.equip_to_slot_if_possible(instanced, use_slot, INV_OP_SILENT | INV_OP_FLUFFLESS)
if(!succeeded)
overflow[instanced] = use_slot
else
if(!(flags & PREF_COPY_TO_SILENT))
to_chat(character, SPAN_NOTICE("Equipping you with \the [instanced]"))
// second pass
for(var/obj/item/instance as anything in overflow)
var/slot = overflow[instance]
if(isnull(slot))
continue
if(character.equip_to_slot_if_possible(instance, slot, INV_OP_SILENT | INV_OP_FLUFFLESS))
overflow -= instance
if(!(flags & PREF_COPY_TO_SILENT))
to_chat(character, SPAN_NOTICE("Equipping you with \the [instance]"))
continue
// storage?
if(allow_storage_spawn)
for(var/obj/item/instance as anything in overflow)
if(character.force_equip_to_slot(instance, /datum/inventory_slot/abstract/put_in_backpack))
overflow -= instance
if(!(flags & PREF_COPY_TO_SILENT))
to_chat(character, SPAN_NOTICE("Putting \the [instance] into your backpack."))
continue
// failed, reject or delete
for(var/obj/item/instance as anything in overflow)
if(!isnull(reject))
reject += instance
else
qdel(instance)
/datum/preferences/proc/overflow_loadout(mob/character, flags, list/obj/item/instances, allow_storage_spawn)
// check allow storage spawns
if(isnull(allow_storage_spawn))
// by default, we only spawn stuff in backpack if they're actually spawning in.
allow_storage_spawn = PREF_COPYING_TO_CHECK_IS_SPAWNING(flags)
// storage?
if(allow_storage_spawn)
for(var/obj/item/instance as anything in instances)
if(character.force_equip_to_slot(instance, /datum/inventory_slot/abstract/put_in_backpack, INV_OP_SILENT))
instances -= instance
if(!(flags & PREF_COPY_TO_SILENT))
to_chat(character, SPAN_NOTICE("Putting \the [instance] into your backpack."))
continue
// failed, reject or delete
for(var/obj/item/instance as anything in instances)
qdel(instance)