GLOBAL_DATUM_INIT(manifest, /datum/manifest, new) /** Stores crew records. */ /datum/manifest /// All of the crew records. var/list/general = list() /// This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). var/list/locked = list() /// Total number of security rapsheet prints. Changes the header. var/print_count = 0 /// Builds the list of crew records for all crew members. /datum/manifest/proc/build() // List of mobs we want to mass insert into the manifest table at round start var/list/players_to_log = list() for(var/mob/dead/new_player/readied_player as anything in GLOB.new_player_list) if(readied_player.new_character) log_manifest(readied_player.ckey, readied_player.new_character.mind, readied_player.new_character) players_to_log[readied_player.ckey] = readied_player.new_character if(ishuman(readied_player.new_character)) inject(readied_player.new_character, null, readied_player.client) // SKYRAT EDIT - RP Records - ORIGINAL: inject(readied_player.new_character) CHECK_TICK if(length(players_to_log)) SSblackbox.ReportRoundstartManifest(players_to_log) /// Gets the current manifest. /datum/manifest/proc/get_manifest() // First we build up the order in which we want the departments to appear in. var/list/manifest_out = list() for(var/datum/job_department/department as anything in SSjob.joinable_departments) manifest_out[department.department_name] = list() manifest_out[DEPARTMENT_UNASSIGNED] = list() var/list/departments_by_type = SSjob.joinable_departments_by_type for(var/datum/record/crew/target as anything in GLOB.manifest.general) var/name = target.name var/rank = target.rank // user-visible job var/trim = target.trim // internal jobs by trim type var/datum/job/job = SSjob.get_job(trim) if(!job || !(job.job_flags & JOB_CREW_MANIFEST) || !LAZYLEN(job.departments_list)) // In case an unlawful custom rank is added. var/list/misc_list = manifest_out[DEPARTMENT_UNASSIGNED] misc_list[++misc_list.len] = list( "name" = name, "rank" = rank, "trim" = trim, ) continue for(var/department_type as anything in job.departments_list) //Jobs under multiple departments should only be displayed if this is their first department or the command department if(job.departments_list[1] != department_type && !(job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)) continue var/datum/job_department/department = departments_by_type[department_type] if(!department) stack_trace("get_manifest() failed to get job department for [department_type] of [job.type]") continue var/list/entry = list( "name" = name, "rank" = rank, "trim" = trim, ) var/list/department_list = manifest_out[department.department_name] if(istype(job, department.department_head)) department_list.Insert(1, null) department_list[1] = entry else department_list[++department_list.len] = entry // Trim the empty categories. for (var/department in manifest_out) if(!length(manifest_out[department])) manifest_out -= department return manifest_out /// Returns the manifest as an html. /datum/manifest/proc/get_html(monochrome = FALSE) var/list/manifest = get_manifest() var/dat = {" "} for(var/department in manifest) var/list/entries = manifest[department] dat += "" //JUST var/even = FALSE for(var/entry in entries) var/list/entry_list = entry dat += "" even = !even dat += "
NameRank
[department]
[entry_list["name"]][entry_list["rank"]]
" dat = replacetext(dat, "\n", "") dat = replacetext(dat, "\t", "") return dat /// Injects a record into the manifest. /datum/manifest/proc/inject(mob/living/carbon/human/person, atom/appearance_proxy, client/person_client) // SKYRAT EDIT - RP Records - ORIGINAL: /datum/manifest/proc/inject(mob/living/carbon/human/person, atom/appearance_proxy) set waitfor = FALSE if(!(person.mind?.assigned_role.job_flags & JOB_CREW_MANIFEST)) return // Attempt to get assignment from ID, otherwise default to mind. var/obj/item/card/id/id_card = person.get_idcard(hand_first = FALSE) var/assignment = id_card?.get_trim_assignment() || person.mind.assigned_role.title var/mutable_appearance/character_appearance = new(appearance_proxy?.appearance || person.appearance) var/person_gender = "Other" if(person.gender == "male") person_gender = "Male" if(person.gender == "female") person_gender = "Female" var/datum/dna/stored/record_dna = new() person.dna.copy_dna(record_dna) // SKYRAT EDIT ADDITION BEGIN - ALTERNATIVE_JOB_TITLES // The alt job title, if user picked one, or the default var/chosen_assignment = id_card?.get_job_title() || assignment //BUBBER EDIT: Intern Job Tags // SKYRAT EDIT ADDITION END - ALTERNATIVE_JOB_TITLES var/datum/record/locked/lockfile = new( age = person.age, chrono_age = person.chrono_age, // SKYRAT EDIT ADDITION - Chronological age blood_type = person.get_bloodtype()?.name || "UNKNOWN", character_appearance = character_appearance, dna_string = record_dna.unique_enzymes, fingerprint = md5(record_dna.unique_identity), gender = person_gender, initial_rank = assignment, name = person.real_name, rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment, species = record_dna.species.name, trim = assignment, // Locked specifics locked_dna = record_dna, mind_ref = person.mind, // BUBBER EDIT ADDITION BEGIN - Records exploitable_information = person_client?.prefs.read_preference(/datum/preference/text/security) || "", // BUBBER EDIT END ) new /datum/record/crew( age = person.age, chrono_age = person.chrono_age, // SKYRAT EDIT ADDITION - Chronological age blood_type = person.get_bloodtype()?.name || "UNKNOWN", character_appearance = character_appearance, dna_string = record_dna.unique_enzymes, fingerprint = md5(record_dna.unique_identity), gender = person_gender, initial_rank = assignment, name = person.real_name, rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment, species = record_dna.species.name, trim = assignment, // Crew specific lock_ref = REF(lockfile), major_disabilities = person.get_quirk_string(FALSE, CAT_QUIRK_MAJOR_DISABILITY, from_scan = TRUE), major_disabilities_desc = person.get_quirk_string(TRUE, CAT_QUIRK_MAJOR_DISABILITY), minor_disabilities = person.get_quirk_string(FALSE, CAT_QUIRK_MINOR_DISABILITY, from_scan = TRUE), minor_disabilities_desc = person.get_quirk_string(TRUE, CAT_QUIRK_MINOR_DISABILITY), quirk_notes = person.get_quirk_string(TRUE, CAT_QUIRK_NOTES), // SKYRAT EDIT START - RP Records past_general_records = person_client?.prefs.read_preference(/datum/preference/text/general) || "", past_medical_records = person_client?.prefs.read_preference(/datum/preference/text/medical) || "", past_security_records = person_client?.prefs.read_preference(/datum/preference/text/security) || "", // SKYRAT EDIT END ) /// Edits the rank and trim of the found record. /datum/manifest/proc/modify(name, assignment, trim) var/datum/record/crew/target = find_record(name) if(!target) return target.rank = assignment target.trim = trim ///Removes a record based on its name. /datum/manifest/proc/remove(name) var/datum/record/crew/target = find_record(name) if(!target) return general -= target qdel(target) /** * Using the name to find the record, and person in reference to the body, we recreate photos for the manifest (and records). * Args: * - name - The name of the record we're looking for, which should be the name of the person. * - person - The mob we're taking pictures of to update the records. * - add_height_chart - If we should add a height chart to the background of the photo. */ /datum/manifest/proc/change_pictures(name, mob/living/person, add_height_chart = FALSE) var/datum/record/crew/target = find_record(name) if(!target) return FALSE target.character_appearance = new(person.appearance) target.recreate_manifest_photos(add_height_chart) return TRUE /datum/manifest/ui_state(mob/user) return GLOB.always_state /datum/manifest/ui_status(mob/user, datum/ui_state/state) return (isnewplayer(user) || isobserver(user) || isAI(user) || ispAI(user) || user.client?.holder) ? UI_INTERACTIVE : UI_CLOSE /datum/manifest/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if (!ui) ui = new(user, src, "CrewManifest") ui.open() /datum/manifest/ui_data(mob/user) var/list/positions = list() for(var/datum/job_department/department as anything in SSjob.joinable_departments) var/open = 0 var/list/exceptions = list() for(var/datum/job/job as anything in department.department_jobs) if(job.total_positions == -1) exceptions += job.title continue var/open_slots = job.total_positions - job.current_positions if(open_slots < 1) continue open += open_slots positions[department.department_name] = list("exceptions" = exceptions, "open" = open) return list( "manifest" = get_manifest(), "positions" = positions )