From 62e2088f54329421a20c83d521c3f911b45aa13d Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 17 Jul 2024 09:02:03 -0400 Subject: [PATCH] ID rework - trait information on IDs, confidential information toggle, and more (#6595) ## About The Pull Request This PR reworks how IDs are displayed, allows for traits to be displayed within IDs, fixes a few things, and generally makes 'em look nicer. This was primarily motivated by https://discord.com/channels/161574200581029888/1262064135110398032 ![dreamseeker_2pBMwy3E2y](https://github.com/user-attachments/assets/ab736d98-3efd-456c-9c48-733dbbc37c07) The screenshot above is how the new IDs look ingame, featuring a few snippets of what a few traits display as within. IDs now properly display the photo (and the generation for said photo has been fixed!), IDs will now show your pronouns, and IDs now have a confidential information section (of which visibility can be toggled by alt-clicking the ID). Additionally, the new feature where traits are displayed on your ID card is something that can be controlled in character generation, under the new "ID-visible traits" section. This section lists all traits you have that feature text for your ID. Clicking a trait will toggle whether or not it's hidden from your ID. This allows traits like vetalism to be omitted from IDs if desired. ![image](https://github.com/user-attachments/assets/e20cc939-ce9f-4048-92ad-ed348aa5f0e3) ## Why It's Good For The Game The primary benefit to this is allowing medical to view potentially important information regarding a patient, such as if they have alcohol intolerance, require blood for their survival, are naturally deaf or blind, and more! All while making sure that information is hidden by default, with the ID needing to be physically held in order to toggle the visibility of that extra information. There's also the additional layer of players being allowed to omit traits from their ID. Additionally, it simply looks quite a bit nicer overall, as IDs now display a preview of the character. ## Changelog :cl: Bhijn and Myr add: The way IDs display information via examine has had an overhaul. They will now display a photo of the employee tied to them, and are now capable of displaying information related to traits. Additionally, confidential information (such as your blood type and trait information) is hidden by default, and their visibility can be toggled by alt-clicking the ID. add: Additionally, character generation has a new section that allows omitting information from IDs outright. /:cl: --- code/datums/outfits/outfit.dm | 2 +- code/datums/uplink/announcements.dm | 4 +- .../objects/items/id_cards/contractor_ids.dm | 6 +- code/game/objects/items/id_cards/guest.dm | 19 ++- .../objects/items/id_cards/station_ids.dm | 120 ++++++++++++------ .../objects/items/id_cards/syndicate_ids.dm | 42 ++---- .../mob/living/carbon/human/traits/_trait.dm | 5 + .../living/carbon/human/traits/negative.dm | 17 +++ .../mob/living/carbon/human/traits/neutral.dm | 11 ++ .../living/carbon/human/traits/positive.dm | 3 + code/modules/preferences/_preferences.dm | 10 ++ .../preference_setup/vore/08_traits.dm | 45 +++++++ code/modules/vore/fluffstuff/custom_items.dm | 4 +- .../mountains/crashedcontainmentshuttle.dmm | 4 +- .../crashedcontainmentshuttle_vr.dmm | 4 +- 15 files changed, 196 insertions(+), 100 deletions(-) diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 8b8ab2b73ed..5c2ef580402 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -93,7 +93,7 @@ post_equip(H) if(W) // We set ID info last to ensure the ID photo is as correct as possible. - H.set_id_info(W) + H.set_id_info(W, H.client) return 1 /datum/outfit/proc/equip_base(mob/living/carbon/human/H) diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm index 737f7c77d67..b339c6b4818 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -60,7 +60,7 @@ general.fields["rank"] = I.assignment general.fields["real_rank"] = I.assignment general.fields["name"] = I.registered_name - general.fields["sex"] = I.sex + general.fields["sex"] = capitalize(user.gender) else var/mob/living/carbon/human/H if(istype(user,/mob/living/carbon/human)) @@ -89,8 +89,6 @@ medical.fields["b_dna"] = random_medical_record.fields["b_type"] if(I) - general.fields["fingerprint"] = I.fingerprint_hash - medical.fields["b_type"] = I.blood_type medical.fields["b_dna"] = I.dna_hash AnnounceArrivalSimple(general.fields["name"], general.fields["rank"]) diff --git a/code/game/objects/items/id_cards/contractor_ids.dm b/code/game/objects/items/id_cards/contractor_ids.dm index 4d6b7482967..6ad380561b6 100644 --- a/code/game/objects/items/id_cards/contractor_ids.dm +++ b/code/game/objects/items/id_cards/contractor_ids.dm @@ -5,10 +5,10 @@ icon_state = "chit" /obj/item/card/id/contractor/dat() + . += "Employing Company: [employing_coperation]" + . += "External Job Title: [extern_title]" + // . += "Expiration Date: [expiry_date]" . = ..() - . += "Employing Company: [employing_coperation]" - . += "External Job Title: [extern_title]" - // . += "Expiration Date: [expiry_date]" /obj/item/card/id/contractor/update_icon() return 0 diff --git a/code/game/objects/items/id_cards/guest.dm b/code/game/objects/items/id_cards/guest.dm index 2678c68b3ba..e28529260bd 100644 --- a/code/game/objects/items/id_cards/guest.dm +++ b/code/game/objects/items/id_cards/guest.dm @@ -52,19 +52,18 @@ else . += "It expired at [worldtime2stationtime(expire_time)]." -/obj/item/card/id/guest/read() - if(!Adjacent(usr)) - return //Too far to read +/obj/item/card/id/guest/get_description_info() + . = ..() if (expired) - to_chat(usr, "This pass expired at [worldtime2stationtime(expire_time)].") + . += SPAN_NOTICE("This pass expired at [worldtime2stationtime(expire_time)].") else - to_chat(usr, "This pass expires at [worldtime2stationtime(expire_time)].") - to_chat(usr, "It grants access to following areas:") + . += SPAN_NOTICE("This pass expires at [worldtime2stationtime(expire_time)].") + . += SPAN_NOTICE("It grants access to following areas:") for (var/A in access) - to_chat(usr, "[get_access_desc(A)].") - to_chat(usr, "Issuing reason: [given_reason].") - to_chat(usr, SPAN_NOTICE("Issuer name: [giver_name]")) - to_chat(usr, SPAN_NOTICE("Issuer rank: [giver_rank]")) + . += SPAN_NOTICE("[get_access_desc(A)].") + . += SPAN_NOTICE("Issuing reason: [given_reason].") + . += SPAN_NOTICE("Issuer name: [giver_name]") + . += SPAN_NOTICE("Issuer rank: [giver_rank]") /obj/item/card/id/guest/attack_self(mob/user) . = ..() diff --git a/code/game/objects/items/id_cards/station_ids.dm b/code/game/objects/items/id_cards/station_ids.dm index 07ba5cc3bb9..f14e2d1b912 100644 --- a/code/game/objects/items/id_cards/station_ids.dm +++ b/code/game/objects/items/id_cards/station_ids.dm @@ -14,13 +14,16 @@ slot_flags = SLOT_ID | SLOT_EARS var/age = "\[UNSET\]" - var/blood_type = "\[UNSET\]" var/dna_hash = "\[UNSET\]" - var/fingerprint_hash = "\[UNSET\]" - var/sex = "\[UNSET\]" + var/pronouns = "\[UNSET\]" var/species = "\[UNSET\]" var/icon/front var/icon/side + var/photoupdatequeued + + /// Keyed list containing confidential information, such as blood type, vetalism, and more + var/list/extra_info = list() + var/extra_info_visible var/last_job_switch var/lost_access = list() @@ -52,15 +55,28 @@ job_access_type = getting_from /obj/item/card/id/examine(mob/user, dist) - var/list/result = dat() - result.Insert(1, ..()) - return result - //show(user) - -/obj/item/card/id/examine_more(mob/user) . = ..() - . += SPAN_NOTICE("You examine [src] closer, and note the following...") - + . += "Alt-click to [extra_info_visible ? "close" : "open"] the confidential information flap.") + return . + +/obj/item/card/id/get_description_info() + . = ..() + if(.) + . += "
" if(mining_points) . += "There's [mining_points] mining equipment redemption point\s loaded onto this card." @@ -102,26 +118,46 @@ return /obj/item/card/id/proc/set_id_photo(var/mob/M) - var/icon/charicon = cached_character_icon(M) - front = icon(charicon,dir = SOUTH) - side = icon(charicon,dir = WEST) + if(!photoupdatequeued) + addtimer(CALLBACK(src, PROC_REF(_set_id_photo)), 1) + photoupdatequeued = M + -/mob/proc/set_id_info(var/obj/item/card/id/id_card) +/obj/item/card/id/proc/_set_id_photo() + var/mob/M = photoupdatequeued + if(istype(M)) + UNTIL(!(M.atom_flags & ATOM_OVERLAY_QUEUED)) // this is necessary specifically because roundstart characters simply do not render their clothes, as they are waiting for overlays to compile. we are in hell we think + front = get_flat_icon(M, SOUTH, TRUE) + side = get_flat_icon(M, WEST, TRUE) + photoupdatequeued = null + +/mob/proc/set_id_info(obj/item/card/id/id_card, client/C) + id_card.extra_info = list() id_card.age = 0 id_card.registered_name = real_name - id_card.sex = capitalize(gender) - id_card.set_id_photo(src) + id_card.extra_info["sex"] = "Biological Sex: [capitalize(gender)]" //most people just use sex for the handful of pixels worth of difference in body model but eh why the hell not + var/datum/gender/G = GLOB.gender_datums[get_gender()] + if(istype(G)) + id_card.pronouns = G.pronoun_preview + else + id_card.pronouns = "Unknown" if(dna) - id_card.blood_type = dna.b_type + id_card.extra_info["bloodtype"] = "Blood Type: [dna.b_type]" + id_card.extra_info["dnahash"] = "DNA Hash: [dna.unique_enzymes]" + id_card.extra_info["fingerprint"] = "Fingerprint: [md5(dna.uni_identity)]" id_card.dna_hash = dna.unique_enzymes - id_card.fingerprint_hash= md5(dna.uni_identity) + if(C && C.prefs) + id_card.extra_info += C.prefs.get_trait_id_info() id_card.update_name() + id_card.set_id_photo(src) -/mob/living/carbon/human/set_id_info(var/obj/item/card/id/id_card) +/mob/living/carbon/human/set_id_info(obj/item/card/id/id_card, client/C) ..() id_card.age = age - id_card.species = src.species.name + id_card.species = custom_species ? custom_species : species.get_examine_name() + + id_card.extra_info["biospecies"] = "Biological Species: [species.get_examine_name()]" if(istype(id_card,/obj/item/card/id/contractor)) var/obj/item/card/id/contractor/c_id = id_card @@ -131,17 +167,20 @@ /obj/item/card/id/proc/dat() var/dat = list() - dat += "Name: [registered_name]" - dat += "Sex: [sex]" - dat += "Age: [age]" - dat += "Rank: [assignment]" - dat += "Species: [species]" - // dat += "Fingerprint: [fingerprint_hash]
\n" - dat += "Blood Type: [blood_type]" - // dat += "DNA Hash: [dna_hash]

\n" - /*if(front && side) - dat +="Photo"*/ - //dat += "" + dat += "Name: [registered_name]" + dat += "Pronouns: [pronouns]" + dat += "Age: [age]" + dat += "Rank: [assignment]" + dat += "Species: [species]" + if(extra_info_visible) + dat += SPAN_NOTICE("
CONFIDENTIAL:") + if(length(extra_info)) + for(var/key in extra_info) // doing a simple dat += extra_info just results in the ID displaying all the keys instead of the actual text tied to 'em + dat += extra_info[key] + else + dat += SPAN_NOTICE("The confidential information section is blank.") + else + dat += "The confidential information flap is closed." return dat /obj/item/card/id/attack_self(mob/user) @@ -154,22 +193,19 @@ src.add_fingerprint(user) return +/obj/item/card/id/AltClick(mob/user) + if(Adjacent(user)) + extra_info_visible = !extra_info_visible + user.visible_message("[user] flips [src]'s confidential information flap [extra_info_visible ? "open" : "closed"].",\ + "You flip [src]'s confidential information flap [extra_info_visible ? "open" : "closed"].") + + /obj/item/card/id/GetAccess() return access.Copy() /obj/item/card/id/GetID() return src -/obj/item/card/id/verb/read() - set name = "Read ID Card" - set category = VERB_CATEGORY_OBJECT - set src in usr - - to_chat(usr, "[icon2html(thing = src, target = usr)] [src.name]: The current assignment on the card is [src.assignment].") - to_chat(usr, "The blood type on the card is [blood_type].") - to_chat(usr, "The DNA hash on the card is [dna_hash].") - to_chat(usr, "The fingerprint hash on the card is [fingerprint_hash].") - /obj/item/card/id/vv_get_dropdown() . = ..() VV_DROPDOWN_OPTION(null, "-----") diff --git a/code/game/objects/items/id_cards/syndicate_ids.dm b/code/game/objects/items/id_cards/syndicate_ids.dm index 87ce989d2a9..a8a4dc4e761 100644 --- a/code/game/objects/items/id_cards/syndicate_ids.dm +++ b/code/game/objects/items/id_cards/syndicate_ids.dm @@ -51,12 +51,10 @@ entries[++entries.len] = list("name" = "Age", "value" = age) entries[++entries.len] = list("name" = "Appearance", "value" = "Set") entries[++entries.len] = list("name" = "Assignment", "value" = assignment) - entries[++entries.len] = list("name" = "Blood Type", "value" = blood_type) entries[++entries.len] = list("name" = "DNA Hash", "value" = dna_hash) - entries[++entries.len] = list("name" = "Fingerprint Hash", "value" = fingerprint_hash) entries[++entries.len] = list("name" = "Name", "value" = registered_name) entries[++entries.len] = list("name" = "Photo", "value" = "Update") - entries[++entries.len] = list("name" = "Sex", "value" = sex) + entries[++entries.len] = list("name" = "Pronouns", "value" = pronouns) entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care") data["electronic_warfare"] = electronic_warfare data["entries"] = entries @@ -122,17 +120,6 @@ to_chat(user, "Occupation changed to '[new_job]'.") update_name() . = 1 - if("Blood Type") - var/default = blood_type - if(default == initial(blood_type) && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna) - default = H.dna.b_type - var/new_blood_type = sanitize(input(user,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text) - if(!isnull(new_blood_type) && CanUseTopic(user, state)) - src.blood_type = new_blood_type - to_chat(user, "Blood type changed to '[new_blood_type]'.") - . = 1 if("DNA Hash") var/default = dna_hash if(default == initial(dna_hash) && ishuman(user)) @@ -144,17 +131,6 @@ src.dna_hash = new_dna_hash to_chat(user, "DNA hash changed to '[new_dna_hash]'.") . = 1 - if("Fingerprint Hash") - var/default = fingerprint_hash - if(default == initial(fingerprint_hash) && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna) - default = md5(H.dna.uni_identity) - var/new_fingerprint_hash = sanitize(input(user,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text) - if(!isnull(new_fingerprint_hash) && CanUseTopic(user, state)) - src.fingerprint_hash = new_fingerprint_hash - to_chat(user, "Fingerprint hash changed to '[new_fingerprint_hash]'.") - . = 1 if("Name") var/new_name = sanitizeName(input(user,"What name would you like to put on this card?","Agent Card Name", registered_name) as null|text) if(!isnull(new_name) && CanUseTopic(user, state)) @@ -166,28 +142,28 @@ set_id_photo(user) to_chat(user, "Photo changed.") . = 1 - if("Sex") - var/new_sex = sanitize(input(user,"What sex would you like to put on this card?","Agent Card Sex", sex) as null|text) - if(!isnull(new_sex) && CanUseTopic(user, state)) - src.sex = new_sex - to_chat(user, "Sex changed to '[new_sex]'.") + if("Pronouns") + var/new_pronouns = sanitize(input(user,"What pronouns would you like to put on this card?","Agent Card Sex", pronouns) as null|text) + if(!isnull(new_pronouns) && CanUseTopic(user, state)) + src.pronouns = new_pronouns + to_chat(user, "Sex changed to '[new_pronouns]'.") . = 1 if("Factory Reset") if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state)) age = initial(age) access = syndicate_access.Copy() assignment = initial(assignment) - blood_type = initial(blood_type) + //blood_type = initial(blood_type) dna_hash = initial(dna_hash) electronic_warfare = initial(electronic_warfare) - fingerprint_hash = initial(fingerprint_hash) + //fingerprint_hash = initial(fingerprint_hash) icon_state = initial(icon_state) sprite_stack = list("") update_icon() name = initial(name) registered_name = initial(registered_name) unset_registered_user() - sex = initial(sex) + pronouns = initial(pronouns) to_chat(user, "All information has been deleted from \the [src].") . = 1 diff --git a/code/modules/mob/living/carbon/human/traits/_trait.dm b/code/modules/mob/living/carbon/human/traits/_trait.dm index 553c79953e9..9e709eb0c28 100644 --- a/code/modules/mob/living/carbon/human/traits/_trait.dm +++ b/code/modules/mob/living/carbon/human/traits/_trait.dm @@ -2,6 +2,11 @@ var/name var/desc = "Contact a developer if you see this trait." + /// Extra IC information about this trait that gets placed within the confidential flap of ID cards + var/extra_id_info + /// Whether or not this trait can have extra info opted out of + var/extra_id_info_optional = TRUE + /// 0 is neutral, negative cost means negative, positive cost means positive. var/cost = 0 /// A list to apply to the custom species vars. diff --git a/code/modules/mob/living/carbon/human/traits/negative.dm b/code/modules/mob/living/carbon/human/traits/negative.dm index 3cf63d3cb80..44e033c2d3f 100644 --- a/code/modules/mob/living/carbon/human/traits/negative.dm +++ b/code/modules/mob/living/carbon/human/traits/negative.dm @@ -14,6 +14,7 @@ name = "Low Endurance" desc = "Reduces your maximum total hitpoints to 75." cost = -2 + extra_id_info = "Employee is unusually susceptible to all forms of harm." var_changes = list("total_health" = 75) /datum/trait/negative/endurance_low/apply(datum/species/S, mob/living/carbon/human/H) @@ -24,6 +25,7 @@ name = "Extremely Low Endurance" desc = "Reduces your maximum total hitpoints to 50." cost = -3 //Teshari HP. This makes the person a lot more suseptable to getting stunned, killed, etc. + extra_id_info = "Employee is extremely susceptible to all forms of harm." var_changes = list("total_health" = 50) /datum/trait/negative/endurance_very_low/apply(datum/species/S, mob/living/carbon/human/H) @@ -46,6 +48,7 @@ name = "Major Brute Weakness" desc = "You take 50% more brute damage" cost = -3 + extra_id_info = "Employee is unusually susceptible to blunt trauma." var_changes = list("brute_mod" = 1.5) /datum/trait/negative/minor_burn_weak @@ -64,6 +67,7 @@ name = "Major Burn Weakness" desc = "You take 50% more burn damage" cost = -3 + extra_id_info = "Employee is unusually sensitive to heat." var_changes = list("burn_mod" = 1.5) /datum/trait/negative/toxin_weak @@ -76,12 +80,14 @@ name = "Major Toxin Weaness" desc = "You take 50% more toxin damage" cost = -2 + extra_id_info = "Employee's organs are ineffective at filtering toxins." var_changes = list("toxins_mod" = 1.5) /datum/trait/negative/oxy_weak name = "Breathe Weakness" desc = "You take 25% more breathe damage and require 25% more air (20kpa minimum). Make sure to adjust your emergency EVA tanks." cost = -1 + extra_id_info = "Employee requires a minimum atmospheric pressure of 20kPa to breathe." var_changes = list("minimum_breath_pressure" = 20, "oxy_mod" = 1.25) /datum/trait/negative/rad_weak @@ -94,6 +100,7 @@ name = "Major Radiation Weakness" desc = "You take 50% more radition damage" cost = -2 + extra_id_info = "Employee is extremely susceptible to radiation." var_changes = list("radiation_mod" = 1.50) /datum/trait/negative/conductive @@ -106,6 +113,7 @@ name = "Major Conductive" desc = "Increases your susceptibility to electric shocks by 100%" cost = -2 + extra_id_info = "Employee is exceptionally conductive." var_changes = list("siemens_coefficient" = 2.0) //This makes you extremely weak to tasers. /datum/trait/negative/hollow @@ -123,6 +131,7 @@ name = "Hollow Bones/Brittle Alloy" desc = "Your bones and robot limbs are significantly easier to break." cost = -4 //I feel like this should be higher, but let's see where it goes + extra_id_info = "Employee's bones are unusually fragile." /datum/trait/negative/hollow_plus/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) @@ -141,6 +150,7 @@ desc = "You simply can't see colors at all, period. You are 100% colorblind." cost = -1 custom_only = FALSE + extra_id_info = "Employee is only capable of perceiving luminance, and cannot perceive hues or saturation." /datum/trait/negative/colorblind/mono/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) @@ -150,6 +160,7 @@ name = "Colorblindness (Para Vulp)" desc = "You have a severe issue with green colors and have difficulty recognizing them from red colors." cost = -1 + extra_id_info = "Employee has a form of red/green colorblindness." /datum/trait/negative/colorblind/para_vulp/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) @@ -159,6 +170,7 @@ name = "Colorblindness (Para Taj)" desc = "You have a minor issue with blue colors and have difficulty recognizing them from red colors." cost = -1 + extra_id_info = "Employee has a form of blue/red colorblindness." /datum/trait/negative/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) @@ -168,6 +180,7 @@ name = "Photosensitive" desc = "You are incredibly vulnerable to bright lights. You are blinded for longer and your skin burns under extreme light." cost = -1 + extra_id_info = "Employee is exceptionally sensitive to bright lights." var_changes = list("flash_mod" = 2) var_changes = list("flash_burn" = 5) @@ -175,6 +188,7 @@ name = "Hemophilia" desc = "You bleed twice as fast as normal." cost = -1 + extra_id_info = "Employee is exceptionally prone to bleeding." var_changes = list("bloodloss_rate" = 2) // todo: use it as a disability? kinda silly this applies forever @@ -182,6 +196,7 @@ name = "Blind" desc = "You're blind. Permanently." cost = -3 + extra_id_info = "Employee has extremely limited vision." custom_only = FALSE excludes = list( /datum/trait/negative/deaf @@ -196,6 +211,7 @@ name = "Deaf" desc = "You're deaf. Permanently." cost = -2 + extra_id_info = "Employee cannot perceive sound." custom_only = FALSE traits = list( TRAIT_DEAF @@ -213,6 +229,7 @@ name = "Mute" desc = "You're mute. Permanently." cost = 0 // TTS bypasses this instantly, no powergaming mute ass explo characters + extra_id_info = "Employee is incapable of vocalizing." custom_only = FALSE traits = list( TRAIT_MUTE diff --git a/code/modules/mob/living/carbon/human/traits/neutral.dm b/code/modules/mob/living/carbon/human/traits/neutral.dm index 37becd2a3aa..c7ea33c9fac 100644 --- a/code/modules/mob/living/carbon/human/traits/neutral.dm +++ b/code/modules/mob/living/carbon/human/traits/neutral.dm @@ -4,6 +4,7 @@ cost = 0 var_changes = list("metabolic_rate" = 1.2, "hunger_factor" = 0.2, "metabolism" = 0.06) // +20% rate and 4x hunger (Teshari level) excludes = list(/datum/trait/neutral/metabolism_down, /datum/trait/neutral/metabolism_apex) + extra_id_info = "Employee has a faster-than-average metabolism." /datum/trait/neutral/metabolism_down name = "Slow Metabolism" @@ -11,6 +12,7 @@ cost = 0 var_changes = list("metabolic_rate" = 0.8, "hunger_factor" = 0.04, "metabolism" = 0.0012) // -20% of default. excludes = list(/datum/trait/neutral/metabolism_up, /datum/trait/neutral/metabolism_apex) + extra_id_info = "Employee has a slower-than-average metabolism." /datum/trait/neutral/metabolism_apex name = "Apex Metabolism" @@ -18,6 +20,7 @@ cost = 0 var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari) excludes = list(/datum/trait/neutral/metabolism_up, /datum/trait/neutral/metabolism_down) + extra_id_info = "Employee has an unusually fast metabolism." /datum/trait/neutral/cold_discomfort name = "Hot-Blooded" @@ -25,6 +28,7 @@ cost = 0 var_changes = list("heat_discomfort_level" = T0C+19) excludes = list(/datum/trait/neutral/hot_discomfort) + extra_id_info = "Employee is acclimated to colder temperatures." /datum/trait/neutral/hot_discomfort name = "Cold-Blooded" @@ -32,6 +36,7 @@ cost = 0 var_changes = list("cold_discomfort_level" = T0C+21) excludes = list(/datum/trait/neutral/cold_discomfort) + extra_id_info = "Employee is acclimated to warmer temperatures." /datum/trait/neutral/autohiss_unathi name = "Autohiss (Unathi)" @@ -67,6 +72,7 @@ cost = 0 var_changes = list("is_vampire" = TRUE) //The verb is given in human.dm custom_only = FALSE + extra_id_info = "Employee's diet is exclusively blood. Employee has tested negative for vetalism." /datum/trait/neutral/bloodsucker/apply(datum/species/S, mob/living/carbon/human/H) ..(S,H) @@ -87,6 +93,7 @@ name = "Vetalan / Vampiric" desc = "Vampires, officially known as the Vetalan, are weaker to burns, bright lights, and must consume blood to survive. To this end, they can see near-perfectly in the darkness, possess sharp, numbing fangs, and anti-septic saliva." cost = 0 + extra_id_info = "Employee is a carrier of Vetalism, and needs to consume blood to survive. Additionally, employee's saliva carries antiseptic properties." custom_only = FALSE var_changes = list( "is_vampire" = TRUE, @@ -243,6 +250,7 @@ desc = "Your saliva has especially strong antiseptic properties that can be used to heal small wounds." cost = 0 custom_only = FALSE + extra_id_info = "Employee's saliva carries antiseptic properties." /datum/trait/neutral/antiseptic_saliva/apply(datum/species/S, mob/living/carbon/human/H) ..(S,H) @@ -265,6 +273,7 @@ var_changes = list( "breath_type" = GAS_ID_NITROGEN ) + extra_id_info = "Employee requires Nitrogen to breathe." /datum/trait/neutral/cyberpsycho name = "Cybernetic Rejection Syndrome" @@ -274,6 +283,7 @@ var_changes = list( "is_cyberpsycho" = TRUE ) + extra_id_info = "Employee's body exhibits violent rejection of cybernetics." /datum/trait/neutral/cyberpsycho/apply(datum/species/S, mob/living/carbon/human/H) ..(S,H) @@ -285,3 +295,4 @@ cost = 0 custom_only = FALSE traits = list(TRAIT_ALCOHOL_INTOLERANT) + extra_id_info = "Employee's body is violently intolerant of alcohol." diff --git a/code/modules/mob/living/carbon/human/traits/positive.dm b/code/modules/mob/living/carbon/human/traits/positive.dm index d1f42234075..b429282bb8f 100644 --- a/code/modules/mob/living/carbon/human/traits/positive.dm +++ b/code/modules/mob/living/carbon/human/traits/positive.dm @@ -96,6 +96,7 @@ desc = "You take 15% less oxygen damge and require 12.5% less air (14kpa minimum)." cost = 2 var_changes = list("minimum_breath_pressure" = 14, "oxy_mod" = 0.85) + extra_id_info = "Employee only requires an atmospheric pressure of 14kPa to breathe." /datum/trait/positive/oxy_resist_plus name = "Breathe Resist" @@ -103,6 +104,7 @@ cost = 3 var_changes = list("minimum_breath_pressure" = 12, "oxy_mod" = 0.75) excludes = list(/datum/trait/positive/oxy_resist,/datum/trait/positive/oxy_resist_plus) + extra_id_info = "Employee only requires an atmospheric pressure of 12kPa to breathe." /datum/trait/positive/rad_resist name = "Minor Radiation Resist" @@ -156,6 +158,7 @@ name = "Antiseptic Saliva" desc = "Your saliva has especially strong antiseptic properties that can be used to heal small wounds." cost = 1 + extra_id_info = "Employee's saliva carries antiseptic properties." /datum/trait/positive/antiseptic_saliva/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() diff --git a/code/modules/preferences/_preferences.dm b/code/modules/preferences/_preferences.dm index 0b8120fe253..406e9d730d7 100644 --- a/code/modules/preferences/_preferences.dm +++ b/code/modules/preferences/_preferences.dm @@ -426,3 +426,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) panel = new(user, "Character Slots", "Character Slots", 300, 390, src) panel.set_content(dat) panel.open() + + +/datum/preferences/proc/get_trait_id_info() + . = list() + for (var/path in (pos_traits + neg_traits + neu_traits) - id_hidden_traits) + var/datum/trait/trait = all_traits[path] + if(istype(trait)) + if(trait.extra_id_info) + .["[ckey(trait.name)]"] = trait.extra_id_info + return . diff --git a/code/modules/preferences/preference_setup/vore/08_traits.dm b/code/modules/preferences/preference_setup/vore/08_traits.dm index 3c797938934..250b388b226 100644 --- a/code/modules/preferences/preference_setup/vore/08_traits.dm +++ b/code/modules/preferences/preference_setup/vore/08_traits.dm @@ -17,6 +17,8 @@ var/list/neu_traits = list() var/list/neg_traits = list() + var/list/id_hidden_traits = list() + var/traits_cheating = 0 //Varedit by admins allows saving new maximums on people who apply/etc var/starting_trait_points = STARTING_SPECIES_POINTS var/max_traits = MAX_SPECIES_TRAITS @@ -32,6 +34,7 @@ S["pos_traits"] >> pref.pos_traits S["neu_traits"] >> pref.neu_traits S["neg_traits"] >> pref.neg_traits + S["hidden_traits"] >> pref.id_hidden_traits S["blood_color"] >> pref.blood_color S["traits_cheating"]>> pref.traits_cheating @@ -49,6 +52,7 @@ S["pos_traits"] << pref.pos_traits S["neu_traits"] << pref.neu_traits S["neg_traits"] << pref.neg_traits + S["hidden_traits"] << pref.id_hidden_traits S["blood_color"] << pref.blood_color S["traits_cheating"]<< pref.traits_cheating @@ -64,6 +68,7 @@ if(!pref.pos_traits) pref.pos_traits = list() if(!pref.neu_traits) pref.neu_traits = list() if(!pref.neg_traits) pref.neg_traits = list() + if(!pref.id_hidden_traits) pref.id_hidden_traits = list() pref.blood_color = sanitize_hexcolor(pref.blood_color, 6, TRUE, default = "#A10808") @@ -82,14 +87,24 @@ for(var/path in pref.neu_traits) if(!(path in neutral_traits)) pref.neu_traits -= path + continue if((pref.real_species_id() != SPECIES_ID_CUSTOM) && !(path in everyone_traits)) pref.neu_traits -= path //Negative traits for(var/path in pref.neg_traits) if(!(path in negative_traits)) pref.neg_traits -= path + continue if((pref.real_species_id() != SPECIES_ID_CUSTOM) && !(path in everyone_traits)) pref.neg_traits -= path + + for(var/path in pref.id_hidden_traits) + var/datum/trait/T = all_traits[path] + if(!istype(T) || !T.extra_id_info_optional) + pref.id_hidden_traits -= path + continue + if(!(path in pref.pos_traits + pref.neu_traits + pref.neg_traits)) + pref.id_hidden_traits -= path var/datum/species/selected_species = pref.real_species_datum() if(selected_species.selects_bodytype) @@ -180,6 +195,23 @@ . += "
  • - [trait.name]
  • " . += "" + var/list/id_traits = list() + for(var/path in pref.pos_traits + pref.neg_traits + pref.neu_traits) + var/datum/trait/T = all_traits[path] + if(istype(T) && T.extra_id_info) + id_traits |= T + + if(length(id_traits)) + . += "ID-visible Traits" + . += "" + . += "
    " + . += "Blood Color: " //People that want to use a certain species to have that species traits (xenochimera/promethean/spider) should be able to set their own blood color. . += "Set Color" . += "R
    " @@ -253,6 +285,19 @@ pref.neg_traits -= trait return PREFERENCES_REFRESH + else if(href_list["id_info_toggle"]) + var/datum/trait/trait = all_traits[text2path(href_list["id_info_toggle"])] + if(!istype(trait)) + to_chat(user, SPAN_WARNING("???")) + return PREFERENCES_REFRESH + if(!(trait.type in pref.id_hidden_traits)) + pref.id_hidden_traits |= trait.type + to_chat(user, SPAN_NOTICE("[trait.name] is now hidden from your ID.")) + else + pref.id_hidden_traits -= trait.type + to_chat(user, "[trait.name] will now be shown on your ID. It will read as: \"[trait.extra_id_info]\"") + return PREFERENCES_REFRESH + else if(href_list["custom_say"]) var/say_choice = sanitize(input(usr, "This word or phrase will appear instead of 'says': [pref.real_name] says, \"Hi.\"", "Custom Say", pref.custom_say) as null|text, 12) if(say_choice) diff --git a/code/modules/vore/fluffstuff/custom_items.dm b/code/modules/vore/fluffstuff/custom_items.dm index 6d71cdef762..0ac75f8d292 100644 --- a/code/modules/vore/fluffstuff/custom_items.dm +++ b/code/modules/vore/fluffstuff/custom_items.dm @@ -1114,8 +1114,8 @@ assignment = "Xenobiology Director" access = list(ACCESS_CENTCOM_GENERAL,ACCESS_CENTCOM_THUNDERDOME,ACCESS_CENTCOM_MEDICAL,ACCESS_CENTCOM_DORMS,ACCESS_CENTCOM_STORAGE,ACCESS_CENTCOM_TELEPORTER,ACCESS_SCIENCE_MAIN,ACCESS_SCIENCE_XENOBIO,ACCESS_ENGINEERING_MAINT,ACCESS_SCIENCE_XENOARCH,ACCESS_SCIENCE_ROBOTICS,ACCESS_SCIENCE_TOXINS,ACCESS_SCIENCE_FABRICATION) //Yes, this looks awful. I tried calling both central and resarch access but it didn't work. age = 39 - blood_type = "O-" - sex = "Female" + //blood_type = "O-" + pronouns = "She/her" /obj/item/fluff/injector //Injectors. Custom item used to explain wild changes in a mob's body or chemistry. name = "Injector" diff --git a/maps/submaps/mountains/crashedcontainmentshuttle.dmm b/maps/submaps/mountains/crashedcontainmentshuttle.dmm index 677e552b5f4..51324af3cdd 100644 --- a/maps/submaps/mountains/crashedcontainmentshuttle.dmm +++ b/maps/submaps/mountains/crashedcontainmentshuttle.dmm @@ -439,13 +439,11 @@ /obj/effect/decal/remains/human, /obj/item/card/id/syndicate{ age = "\\42"; - blood_type = "\\O+"; desc = "A strange ID card."; dna_hash = "\[REDACTED]"; - fingerprint_hash = "\\------"; name = "Aaron Presley's ID Card(Delivery Service) "; registered_name = "Aaron Presley"; - sex = "\\Male" + pronouns = "\\He/him" }, /turf/simulated/shuttle/floor/white, /area/submap/crashedcontainmentshuttle) diff --git a/maps/submaps/mountains/crashedcontainmentshuttle_vr.dmm b/maps/submaps/mountains/crashedcontainmentshuttle_vr.dmm index 44abe47d5fd..d93d3361f57 100644 --- a/maps/submaps/mountains/crashedcontainmentshuttle_vr.dmm +++ b/maps/submaps/mountains/crashedcontainmentshuttle_vr.dmm @@ -386,13 +386,11 @@ /obj/effect/decal/remains/human, /obj/item/card/id/syndicate{ age = "\\42"; - blood_type = "\\O+"; desc = "A strange ID card."; dna_hash = "\[REDACTED]"; - fingerprint_hash = "\\------"; name = "Aaron Presley's ID Card(Delivery Service) "; registered_name = "Aaron Presley"; - sex = "\\Male" + pronouns = "\\He/him" }, /turf/simulated/shuttle/floor/white, /area/submap/crashedcontainmentshuttle)