# Conflicts:
#	code/game/jobs/job/science.dm
#	code/modules/mob/living/carbon/human/species/station/human_subspecies.dm
#	code/modules/mob/living/carbon/human/species/station/seromi.dm
#	code/modules/mob/living/silicon/robot/robot_modules/station.dm
#	config/custom_items.txt
This commit is contained in:
Kelshark
2017-10-29 18:14:56 -04:00
478 changed files with 18926 additions and 4360 deletions
@@ -12,6 +12,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
S["real_name"] >> pref.real_name
S["nickname"] >> pref.nickname
S["name_is_always_random"] >> pref.be_random_name
S["gender"] >> pref.biological_gender
S["id_gender"] >> pref.identifying_gender
@@ -21,6 +22,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
/datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S)
S["real_name"] << pref.real_name
S["nickname"] << pref.nickname
S["name_is_always_random"] << pref.be_random_name
S["gender"] << pref.biological_gender
S["id_gender"] << pref.identifying_gender
@@ -35,6 +37,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
pref.real_name = sanitize_name(pref.real_name, pref.species, is_FBP())
if(!pref.real_name)
pref.real_name = random_name(pref.identifying_gender, pref.species)
pref.nickname = sanitize_name(pref.nickname)
pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint))
pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name))
@@ -53,6 +56,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
if(character.dna)
character.dna.real_name = character.real_name
character.nickname = pref.nickname
character.gender = pref.biological_gender
character.identifying_gender = pref.identifying_gender
character.age = pref.age
@@ -62,7 +67,9 @@ datum/preferences/proc/set_biological_gender(var/gender)
. += "<b>Name:</b> "
. += "<a href='?src=\ref[src];rename=1'><b>[pref.real_name]</b></a><br>"
. += "<a href='?src=\ref[src];random_name=1'>Randomize Name</A><br>"
. += "<a href='?src=\ref[src];always_random_name=1'>Always Random Name: [pref.be_random_name ? "Yes" : "No"]</a>"
. += "<a href='?src=\ref[src];always_random_name=1'>Always Random Name: [pref.be_random_name ? "Yes" : "No"]</a><br>"
. += "<b>Nickname:</b> "
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
. += "<br>"
. += "<b>Biological Gender:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Gender Identity:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
@@ -92,6 +99,17 @@ datum/preferences/proc/set_biological_gender(var/gender)
pref.be_random_name = !pref.be_random_name
return TOPIC_REFRESH
else if(href_list["nickname"])
var/raw_nickname = input(user, "Choose your character's nickname:", "Character Nickname") as text|null
if (!isnull(raw_nickname) && CanUseTopic(user))
var/new_nickname = sanitize_name(raw_nickname, pref.species, is_FBP())
if(new_nickname)
pref.nickname = new_nickname
return TOPIC_REFRESH
else
user << "<span class='warning'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</span>"
return TOPIC_NOACTION
else if(href_list["bio_gender"])
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
if(new_gender && CanUseTopic(user))
@@ -29,6 +29,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["organ_data"] >> pref.organ_data
S["rlimb_data"] >> pref.rlimb_data
S["body_markings"] >> pref.body_markings
S["synth_color"] >> pref.synth_color
S["synth_red"] >> pref.r_synth
S["synth_green"] >> pref.g_synth
S["synth_blue"] >> pref.b_synth
pref.preview_icon = null
/datum/category_item/player_setup_item/general/body/save_character(var/savefile/S)
@@ -53,6 +57,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["organ_data"] << pref.organ_data
S["rlimb_data"] << pref.rlimb_data
S["body_markings"] << pref.body_markings
S["synth_color"] << pref.synth_color
S["synth_red"] << pref.r_synth
S["synth_green"] << pref.g_synth
S["synth_blue"] << pref.b_synth
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
if(!pref.species || !(pref.species in playable_species))
@@ -101,6 +109,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
character.h_style = pref.h_style
character.f_style = pref.f_style
character.b_type = pref.b_type
character.synth_color = pref.synth_color
character.r_synth = pref.r_synth
character.g_synth = pref.g_synth
character.b_synth = pref.b_synth
// Destroy/cyborgize organs and limbs.
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
@@ -284,6 +296,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
. += "<br>"
. += "<br>"
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
if(pref.synth_color)
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth)]'><tr><td>__</td></tr></table></font> "
. = jointext(.,null)
/datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag)
@@ -672,6 +689,18 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.equip_preview_mob ^= text2num(href_list["toggle_preview_value"])
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth_color"])
pref.synth_color = !pref.synth_color
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth2_color"])
var/new_color = input(user, "Choose your character's synth colour: ", "Character Preference", rgb(pref.r_synth, pref.g_synth, pref.b_synth)) as color|null
if(new_color && CanUseTopic(user))
pref.r_synth = hex2num(copytext(new_color, 2, 4))
pref.g_synth = hex2num(copytext(new_color, 4, 6))
pref.b_synth = hex2num(copytext(new_color, 6, 8))
return TOPIC_REFRESH_UPDATE_PREVIEW
return ..()
/datum/category_item/player_setup_item/general/body/proc/reset_limbs()
@@ -704,7 +733,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if("preview" in icon_states(current_species.icobase))
usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png")
dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>"
dat += "<b>Language:</b> [current_species.language]<br/>"
dat += "<b>Language:</b> [current_species.species_language]<br/>"
dat += "<small>"
if(current_species.spawn_flags & SPECIES_CAN_JOIN)
dat += "</br><b>Often present on human stations.</b>"
@@ -14,7 +14,8 @@ var/list/gear_datums = list()
//create a list of gear datums to sort
for(var/geartype in typesof(/datum/gear)-/datum/gear)
var/datum/gear/G = geartype
if(initial(G.type_category) == geartype)
continue
var/use_name = initial(G.display_name)
var/use_category = initial(G.sort_category)
@@ -205,6 +206,7 @@ var/list/gear_datums = list()
var/sort_category = "General"
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
var/exploitable = 0 //Does it go on the exploitable information list?
var/type_category = null
/datum/gear/New()
..()
@@ -1,42 +1,28 @@
/datum/gear/accessory
display_name = "armband, red"
path = /obj/item/clothing/accessory/armband
display_name = "accessory"
slot = slot_tie
sort_category = "Accessories"
type_category = /datum/gear/accessory
path = /obj/item/clothing/accessory
cost = 1
/datum/gear/accessory/cargo
display_name = "armband, cargo"
path = /obj/item/clothing/accessory/armband/cargo
/datum/gear/accessory/armband
display_name = "armband selection"
path = /obj/item/clothing/accessory/armband
/datum/gear/accessory/emt
display_name = "armband, EMT"
path = /obj/item/clothing/accessory/armband/medblue
/datum/gear/accessory/armband/New()
..()
var/list/armbands = list()
for(var/armband in (typesof(/obj/item/clothing/accessory/armband) - typesof(/obj/item/clothing/accessory/armband/med/color)))
var/obj/item/clothing/accessory/armband_type = armband
armbands[initial(armband_type.name)] = armband_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(armbands))
/datum/gear/accessory/engineering
display_name = "armband, engineering"
path = /obj/item/clothing/accessory/armband/engine
/datum/gear/accessory/hydroponics
display_name = "armband, hydroponics"
path = /obj/item/clothing/accessory/armband/hydro
/datum/gear/accessory/medical
display_name = "armband, medical"
path = /obj/item/clothing/accessory/armband/med
/datum/gear/accessory/medical/cross
display_name = "armband, medic"
path = /obj/item/clothing/accessory/armband/med/cross
/datum/gear/accessory/science
display_name = "armband, science"
path = /obj/item/clothing/accessory/armband/science
/datum/gear/accessory/colored
/datum/gear/accessory/armband/colored
display_name = "armband"
path = /obj/item/clothing/accessory/armband/med/color
/datum/gear/accessory/colored/New()
/datum/gear/accessory/armband/colored/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
@@ -74,215 +60,109 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/accessory/wcoat
display_name = "waistcoat"
display_name = "waistcoat selection"
path = /obj/item/clothing/accessory/wcoat
cost = 1
/datum/gear/accessory/wcoat/red
display_name = "waistcoat, red"
path = /obj/item/clothing/accessory/wcoat/red
/datum/gear/accessory/wcoat/grey
display_name = "waistcoat, grey"
path = /obj/item/clothing/accessory/wcoat/grey
/datum/gear/accessory/wcoat/brown
display_name = "waistcoat, brown"
path = /obj/item/clothing/accessory/wcoat/brown
/datum/gear/accessory/swvest
display_name = "sweatervest, black"
path = /obj/item/clothing/accessory/wcoat/swvest
cost = 1
/datum/gear/accessory/swvest/blue
display_name = "sweatervest, blue"
path = /obj/item/clothing/accessory/wcoat/swvest/blue
/datum/gear/accessory/swvest/red
display_name = "sweatervest, red"
path = /obj/item/clothing/accessory/wcoat/swvest/red
/datum/gear/accessory/wcoat/New()
..()
var/list/wcoats = list()
for(var/wcoat in typesof(/obj/item/clothing/accessory/wcoat))
var/obj/item/clothing/accessory/wcoat_type = wcoat
wcoats[initial(wcoat_type.name)] = wcoat_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(wcoats))
/datum/gear/accessory/holster
display_name = "holster, armpit"
path = /obj/item/clothing/accessory/holster/armpit
display_name = "holster selection (Security, CD, HoP)"
path = /obj/item/clothing/accessory/holster
allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective")
/datum/gear/accessory/holster/hip
display_name = "holster, hip"
path = /obj/item/clothing/accessory/holster/hip
/datum/gear/accessory/holster/leg
display_name = "holster, leg"
path = /obj/item/clothing/accessory/holster/leg
/datum/gear/accessory/holster/waist
display_name = "holster, waist"
path = /obj/item/clothing/accessory/holster/waist
/datum/gear/accessory/holster/New()
..()
var/list/holsters = list()
for(var/holster in typesof(/obj/item/clothing/accessory/holster))
var/obj/item/clothing/accessory/holster_type = holster
holsters[initial(holster_type.name)] = holster_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(holsters))
/datum/gear/accessory/tie
display_name = "tie, black"
path = /obj/item/clothing/accessory/black
display_name = "tie selection"
path = /obj/item/clothing/accessory/tie
cost = 1
/datum/gear/accessory/tie/blue
display_name = "tie, blue"
path = /obj/item/clothing/accessory/blue
/datum/gear/accessory/tie/blue_clip
display_name = "tie, blue with clip"
path = /obj/item/clothing/accessory/blue_clip
/datum/gear/accessory/tie/blue_long
display_name = "tie, blue long"
path = /obj/item/clothing/accessory/blue_long
/datum/gear/accessory/tie/red
display_name = "tie, red"
path = /obj/item/clothing/accessory/red
/datum/gear/accessory/tie/red_clip
display_name = "tie, red with clip"
path = /obj/item/clothing/accessory/red_clip
/datum/gear/accessory/tie/red_long
display_name = "tie, red long"
path = /obj/item/clothing/accessory/red_long
/datum/gear/accessory/tie/yellow
display_name = "tie, yellow"
path = /obj/item/clothing/accessory/yellow
/datum/gear/accessory/tie/navy
display_name = "tie, navy blue"
path = /obj/item/clothing/accessory/navy
/datum/gear/accessory/tie/white
display_name = "tie, white"
path = /obj/item/clothing/accessory/white
/datum/gear/accessory/tie/horrible
display_name = "tie, socially disgraceful"
path = /obj/item/clothing/accessory/horrible
/datum/gear/accessory/tie/New()
..()
var/list/ties = list()
for(var/tie in typesof(/obj/item/clothing/accessory/tie))
var/obj/item/clothing/accessory/tie_type = tie
ties[initial(tie_type.name)] = tie_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(ties))
/datum/gear/accessory/scarf
display_name = "scarf"
display_name = "scarf selection"
path = /obj/item/clothing/accessory/scarf
cost = 1
/datum/gear/accessory/scarf/red
display_name = "scarf, red"
path = /obj/item/clothing/accessory/scarf/red
/datum/gear/accessory/scarf/New()
..()
var/list/scarfs = list()
for(var/scarf in typesof(/obj/item/clothing/accessory/scarf))
var/obj/item/clothing/accessory/scarf_type = scarf
scarfs[initial(scarf_type.name)] = scarf_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(scarfs))
/datum/gear/accessory/scarf/green
display_name = "scarf, green"
path = /obj/item/clothing/accessory/scarf/green
/datum/gear/accessory/jacket
display_name = "suit jacket selection"
path = /obj/item/clothing/accessory/jacket
cost = 1
/datum/gear/accessory/scarf/darkblue
display_name = "scarf, dark blue"
path = /obj/item/clothing/accessory/scarf/darkblue
/datum/gear/accessory/scarf/purple
display_name = "scarf, purple"
path = /obj/item/clothing/accessory/scarf/purple
/datum/gear/accessory/scarf/yellow
display_name = "scarf, yellow"
path = /obj/item/clothing/accessory/scarf/yellow
/datum/gear/accessory/scarf/orange
display_name = "scarf, orange"
path = /obj/item/clothing/accessory/scarf/orange
/datum/gear/accessory/scarf/lightblue
display_name = "scarf, light blue"
path = /obj/item/clothing/accessory/scarf/lightblue
/datum/gear/accessory/scarf/white
display_name = "scarf, white"
path = /obj/item/clothing/accessory/scarf/white
/datum/gear/accessory/scarf/black
display_name = "scarf, black"
path = /obj/item/clothing/accessory/scarf/black
/datum/gear/accessory/scarf/zebra
display_name = "scarf, zebra"
path = /obj/item/clothing/accessory/scarf/zebra
/datum/gear/accessory/scarf/christmas
display_name = "scarf, christmas"
path = /obj/item/clothing/accessory/scarf/christmas
/datum/gear/accessory/scarf/stripedred
display_name = "scarf, striped red"
path = /obj/item/clothing/accessory/stripedredscarf
/datum/gear/accessory/scarf/stripedgreen
display_name = "scarf, striped green"
path = /obj/item/clothing/accessory/stripedgreenscarf
/datum/gear/accessory/scarf/stripedblue
display_name = "scarf, striped blue"
path = /obj/item/clothing/accessory/stripedbluescarf
/datum/gear/accessory/suitjacket
display_name = "suit jacket, tan"
path = /obj/item/clothing/accessory/tan_jacket
/datum/gear/accessory/suitjacket/charcoal
display_name = "suit jacket, charcoal"
path = /obj/item/clothing/accessory/charcoal_jacket
/datum/gear/accessory/suitjacket/navy
display_name = "suit jacket, navy blue"
path = /obj/item/clothing/accessory/navy_jacket
/datum/gear/accessory/suitjacket/burgundy
display_name = "suit jacket, burgundy"
path = /obj/item/clothing/accessory/burgundy_jacket
/datum/gear/accessory/suitjacket/checkered
display_name = "suit jacket, checkered"
path = /obj/item/clothing/accessory/checkered_jacket
/datum/gear/accessory/jacket/New()
..()
var/list/jackets = list()
for(var/jacket in typesof(/obj/item/clothing/accessory/jacket))
var/obj/item/clothing/accessory/jacket_type = jacket
jackets[initial(jacket_type.name)] = jacket_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(jackets))
/datum/gear/accessory/suitvest
display_name = "suit vest"
path = /obj/item/clothing/accessory/vest
/datum/gear/accessory/brown_vest
display_name = "webbing, engineering"
display_name = "webbing, brown"
path = /obj/item/clothing/accessory/storage/brown_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/black_vest
display_name = "webbing, security"
display_name = "webbing, black"
path = /obj/item/clothing/accessory/storage/black_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/white_vest
display_name = "webbing, medical"
display_name = "webbing, white"
path = /obj/item/clothing/accessory/storage/white_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/brown_drop_pouches
display_name = "drop pouches, engineering"
display_name = "drop pouches, brown"
path = /obj/item/clothing/accessory/storage/brown_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/black_drop_pouches
display_name = "drop pouches, security"
display_name = "drop pouches, black"
path = /obj/item/clothing/accessory/storage/black_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/white_drop_pouches
display_name = "drop pouches, medical"
display_name = "drop pouches, white"
path = /obj/item/clothing/accessory/storage/white_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/fannypack
display_name = "fannypack selection"
cost = 2
path = /obj/item/weapon/storage/belt/fannypack
/datum/gear/accessory/fannypack/New()
..()
@@ -26,6 +26,9 @@
display_name = "Collar, Pink"
path = /obj/item/clothing/accessory/collar/pink
/datum/gear/collar/holo
display_name = "Collar, Holo"
path = /obj/item/clothing/accessory/collar/holo
/datum/gear/accessory/white_drop_pouches
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist")
@@ -55,4 +58,4 @@
/datum/gear/accessory/tronket
display_name = "Metal necklace"
description = "A shiny steel chain with a vague metallic object dangling off it."
path = /obj/item/clothing/accessory/tronket
path = /obj/item/clothing/accessory/tronket
@@ -61,16 +61,16 @@
/datum/gear/eyes/medical/aviator
display_name = "Medical HUD Aviators (Medical)"
path = /obj/item/clothing/glasses/sunglasses/medhud/aviator
path = /obj/item/clothing/glasses/hud/health/aviator
/datum/gear/eyes/medical/aviator/prescription
display_name = "Medical HUD Aviators, prescription (Medical)"
path = /obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription
path = /obj/item/clothing/glasses/hud/health/aviator/prescription
/datum/gear/eyes/meson
display_name = "Optical Meson Scanners (Engineering)"
display_name = "Optical Meson Scanners (Engineering, Science)"
path = /obj/item/clothing/glasses/meson
allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician")
allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician", "Scientist", "Research Director")
/datum/gear/eyes/meson/prescription
display_name = "Optical Meson Scanners, prescription (Engineering)"
@@ -93,8 +93,6 @@
display_name = "Optical Meson Aviators, prescription (Engineering)"
path = /obj/item/clothing/glasses/meson/aviator/prescription
/datum/gear/eyes/meson/aviator/prescription
/datum/gear/eyes/glasses/fakesun
display_name = "Sunglasses, stylish"
path = /obj/item/clothing/glasses/fakesunglasses
@@ -112,7 +110,10 @@
display_name = "Sunglasses, fat (Security/Command)"
path = /obj/item/clothing/glasses/sunglasses/big
/datum/gear/eyes/sun/aviators
display_name = "Sunglasses, aviators (Security/Command)"
path = /obj/item/clothing/glasses/sunglasses/aviator
/datum/gear/eyes/sun/prescriptionsun
display_name = "sunglasses, presciption (Security/Command)"
path = /obj/item/clothing/glasses/sunglasses/prescription
cost = 2
@@ -68,10 +68,34 @@
cost = 3
/datum/gear/gloves/forensic
display_name = "gloves, forensic"
display_name = "gloves, forensic (Detective)"
path = /obj/item/clothing/gloves/forensic
allowed_roles = list("Detective")
/datum/gear/gloves/fingerless
display_name = "fingerless gloves"
path = /obj/item/clothing/gloves/fingerless
path = /obj/item/clothing/gloves/fingerless
/datum/gear/gloves/ring
display_name = "ring selection"
description = "Choose from a number of rings."
path = /obj/item/clothing/gloves/ring
cost = 1
/datum/gear/gloves/ring/New()
..()
var/ringtype = list()
ringtype["CTI ring"] = /obj/item/clothing/gloves/ring/cti
ringtype["Mariner University ring"] = /obj/item/clothing/gloves/ring/mariner
ringtype["engagement ring"] = /obj/item/clothing/gloves/ring/engagement
ringtype["signet ring"] = /obj/item/clothing/gloves/ring/seal/signet
ringtype["masonic ring"] = /obj/item/clothing/gloves/ring/seal/mason
ringtype["ring, steel"] = /obj/item/clothing/gloves/ring/material/steel
ringtype["ring, iron"] = /obj/item/clothing/gloves/ring/material/iron
ringtype["ring, silver"] = /obj/item/clothing/gloves/ring/material/silver
ringtype["ring, gold"] = /obj/item/clothing/gloves/ring/material/gold
ringtype["ring, platinum"] = /obj/item/clothing/gloves/ring/material/platinum
ringtype["ring, glass"] = /obj/item/clothing/gloves/ring/material/glass
ringtype["ring, wood"] = /obj/item/clothing/gloves/ring/material/wood
ringtype["ring, plastic"] = /obj/item/clothing/gloves/ring/material/plastic
gear_tweaks += new/datum/gear_tweak/path(ringtype)
@@ -136,7 +136,6 @@
/datum/gear/head/cowboy
display_name = "cowboy, rodeo"
path = /obj/item/clothing/head/cowboy_hat
cost = 3
/datum/gear/head/cowboy/black
display_name = "cowboy, black"
@@ -268,6 +267,11 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/head/kitty
display_name = "kitty ears"
path = /obj/item/clothing/head/kitty
/datum/gear/head/beanie
display_name = "beanie"
path = /obj/item/clothing/head/beanie
@@ -195,6 +195,10 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/shoes/slippers
display_name = "bunny slippers"
path = /obj/item/clothing/shoes/slippers
/datum/gear/shoes/boots/winter
display_name = "winter boots"
path = /obj/item/clothing/shoes/boots/winter
@@ -227,7 +231,7 @@
/datum/gear/shoes/boots/winter/medical
display_name = "medical winter boots"
path = /obj/item/clothing/shoes/boots/winter/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/shoes/boots/winter/mining
display_name = "mining winter boots"
@@ -149,7 +149,7 @@
/datum/gear/suit/labcoat/emt
display_name = "labcoat, EMT (Medical)"
path = /obj/item/clothing/suit/storage/toggle/labcoat/emt
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/roles/surgical_apron
display_name = "surgical apron"
@@ -182,7 +182,7 @@
/datum/gear/suit/roles/poncho/medical
display_name = "poncho, medical"
path = /obj/item/clothing/accessory/poncho/roles/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/roles/poncho/engineering
display_name = "poncho, engineering"
@@ -199,6 +199,41 @@
path = /obj/item/clothing/accessory/poncho/roles/cargo
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/suit/roles/poncho/cloak/hos
display_name = "cloak, head of security"
path = /obj/item/clothing/accessory/poncho/roles/cloak/hos
allowed_roles = list("Head of Security")
/datum/gear/suit/roles/poncho/cloak/cmo
display_name = "cloak, chief medical officer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/cmo
allowed_roles = list("Chief Medical Officer")
/datum/gear/suit/roles/poncho/cloak/ce
display_name = "cloak, chief engineer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/ce
allowed_roles = list("Chief Engineer")
/datum/gear/suit/roles/poncho/cloak/rd
display_name = "cloak, research director"
path = /obj/item/clothing/accessory/poncho/roles/cloak/rd
allowed_roles = list("Research Director")
/datum/gear/suit/roles/poncho/cloak/qm
display_name = "cloak, quartermaster"
path = /obj/item/clothing/accessory/poncho/roles/cloak/qm
allowed_roles = list("Quartermaster")
/datum/gear/suit/roles/poncho/cloak/captain
display_name = "cloak, colony director"
path = /obj/item/clothing/accessory/poncho/roles/cloak/captain
allowed_roles = list("Colony Director")
/datum/gear/suit/roles/poncho/cloak/hop
display_name = "cloak, head of personnel"
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
allowed_roles = list("Head of Personnel")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -257,7 +292,7 @@
/datum/gear/suit/wintercoat/medical
display_name = "winter coat, medical"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/wintercoat/science
display_name = "winter coat, science"
@@ -410,7 +445,7 @@
/datum/gear/suit/snowsuit/medical
display_name = "snowsuit, medical"
path = /obj/item/clothing/suit/storage/snowsuit/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/snowsuit/science
display_name = "snowsuit, science"
@@ -243,7 +243,6 @@
/datum/gear/uniform/scrub
display_name = "scrubs selection"
path = /obj/item/clothing/under/rank/medical/scrubs
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Roboticist")
/datum/gear/uniform/scrub/New()
..()
@@ -455,3 +454,7 @@
/datum/gear/uniform/red_swept_dress
display_name = "red swept dress"
path = /obj/item/clothing/under/dress/red_swept_dress
/datum/gear/uniform/bathrobe
display_name = "bathrobe"
path = /obj/item/clothing/under/bathrobe
@@ -89,12 +89,14 @@
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 10
slot = "implant"
exploitable = 1
/datum/gear/utility/translator
display_name = "universal translator"
@@ -157,7 +157,7 @@
var/datum/job/job = locate(href_list["select_alt_title"])
if (job)
var/choices = list(job.title) + job.alt_titles
var/choice = input("Choose an title for [job.title].", "Choose Title", pref.GetPlayerAltTitle(job)) as anything in choices|null
var/choice = input("Choose a title for [job.title].", "Choose Title", pref.GetPlayerAltTitle(job)) as anything in choices|null
if(choice && CanUseTopic(user))
SetPlayerAltTitle(job, choice)
return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH)
@@ -32,10 +32,15 @@
name = "Loadout"
sort_order = 5
category_item_type = /datum/category_item/player_setup_item/loadout
/* //VOREStation Removal
/datum/category_group/player_setup_category/trait_preferences
name = "Traits"
sort_order = 6
category_item_type = /datum/category_item/player_setup_item/traits
*/ //VOREStation Removal End
/datum/category_group/player_setup_category/global_preferences
name = "Global"
sort_order = 6
sort_order = 6 //VOREStation Edit due to above commented out
category_item_type = /datum/category_item/player_setup_item/player_global
/****************************
@@ -0,0 +1,223 @@
// This contains character setup datums for traits.
// The actual modifiers (if used) for these are stored inside code/modules/mob/_modifiers/traits.dm
/datum/trait/modifier
var/modifier_type = null // Type to add to the mob post spawn.
/datum/trait/modifier/apply_trait_post_spawn(mob/living/L)
L.add_modifier(modifier_type)
/datum/trait/modifier/generate_desc()
var/new_desc = desc
if(!modifier_type)
new_desc = "[new_desc] This trait is not implemented yet."
return new_desc
var/datum/modifier/M = new modifier_type()
if(!desc)
new_desc = M.desc // Use the modifier's description, if the trait doesn't have one defined.
var/modifier_effects = M.describe_modifier_effects()
new_desc = "[new_desc][modifier_effects ? "<br>[modifier_effects]":""]" // Now describe what the trait actually does.
qdel(M)
return new_desc
// Physical traits are what they sound like, and involve the character's physical body, as opposed to their mental state.
/datum/trait/modifier/physical
category = "Physical Quirks" //VOREStation Edit
/datum/trait/modifier/physical/flimsy
name = "Flimsy"
desc = "You're more fragile than most, and have less of an ability to endure harm."
modifier_type = /datum/modifier/trait/flimsy
mutually_exclusive = list(/datum/trait/modifier/physical/frail)
/datum/trait/modifier/physical/frail
name = "Frail"
desc = "Your body is very fragile, and has even less of an ability to endure harm."
modifier_type = /datum/modifier/trait/frail
mutually_exclusive = list(/datum/trait/modifier/physical/flimsy)
/datum/trait/modifier/physical/haemophilia
name = "Haemophilia"
desc = "Some say that when it rains, it pours. Unfortunately, this is also true for yourself if you get cut."
modifier_type = /datum/modifier/trait/haemophilia
/datum/trait/modifier/physical/haemophilia/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot bleed."
// If a species lacking blood is added, it is suggested to add a check for them here.
return ..()
/datum/trait/modifier/physical/weak
name = "Weak"
desc = "A lack of physical strength causes a diminshed capability in close quarters combat."
modifier_type = /datum/modifier/trait/weak
mutually_exclusive = list(/datum/trait/modifier/physical/wimpy)
/datum/trait/modifier/physical/wimpy
name = "Wimpy"
desc = "An extreme lack of physical strength causes a greatly diminished capability in close quarters combat."
modifier_type = /datum/modifier/trait/wimpy
mutually_exclusive = list(/datum/trait/modifier/physical/weak)
/datum/trait/modifier/physical/inaccurate
name = "Inaccurate"
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
Regardless, you find it quite difficult to land shots where you wanted them to go."
modifier_type = /datum/modifier/trait/inaccurate
// These two traits might be borderline, feel free to remove if they get abused.
/datum/trait/modifier/physical/high_metabolism
name = "High Metabolism"
modifier_type = /datum/modifier/trait/high_metabolism
mutually_exclusive = list(/datum/trait/modifier/physical/low_metabolism)
/datum/trait/modifier/physical/high_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics do not have a metabolism."
return ..()
/datum/trait/modifier/physical/low_metabolism
name = "Low Metabolism"
modifier_type = /datum/modifier/trait/low_metabolism
mutually_exclusive = list(/datum/trait/modifier/physical/high_metabolism)
/datum/trait/modifier/physical/low_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics do not have a metabolism."
return ..()
/datum/trait/modifier/physical/cloned
name = "Cloned"
desc = "At some point in your life, you died and were cloned."
modifier_type = /datum/modifier/cloned
/datum/trait/modifier/physical/cloned/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot be cloned."
return ..()
/datum/trait/modifier/physical/no_clone
name = "Cloning Incompatability"
modifier_type = /datum/modifier/no_clone
/datum/trait/modifier/physical/no_clone/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot be cloned anyways."
return ..()
/datum/trait/modifier/physical/no_borg
name = "Cybernetic Incompatability"
modifier_type = /datum/modifier/no_borg
/datum/trait/modifier/physical/no_borg/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics are already partly or fully mechanical."
return ..()
// 'Mental' traits are just those that only sapients can have, for now, and generally involves fears.
// So far, all of them are just for fluff/don't have mechanical effects.
/datum/trait/modifier/mental
category = "Mental"
/datum/trait/modifier/mental/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
if(setup.get_FBP_type() == PREF_FBP_SOFTWARE)
return "Drone Intelligences cannot feel emotions."
return ..()
/datum/trait/modifier/mental/arachnophobe
name = "Arachnophobic"
desc = "Spiders are quite creepy to most people, however for you, those chitters of pure evil inspire pure dread and fear."
modifier_type = /datum/modifier/trait/phobia/arachnophobe
/datum/trait/modifier/mental/nyctophobe
name = "Nyctophobic"
desc = "More commonly known as the fear of darkness. The shadows can hide many dangers, which makes the prospect of going into the depths of Maintenance rather worrisome."
modifier_type = /datum/modifier/trait/phobia/nyctophobe
/datum/trait/modifier/mental/haemophobe
name = "Haemophobia"
desc = "Not to be confused with Haemophilia (which makes you bleed faster), Haemophobia is the fear of blood. Seeing a bunch of blood isn't really \
pleasant for most people, but for you, it is very distressing."
modifier_type = /datum/modifier/trait/phobia/haemophobia
/datum/trait/modifier/mental/claustrophobe
name = "Claustrophobic"
desc = "Small spaces and tight quarters makes you feel distressed. Unfortunately both are rather common when living in space."
modifier_type = /datum/modifier/trait/phobia/claustrophobe
/*
// Uncomment this when/if these get finished.
/datum/trait/modifier/mental/synthphobe
name = "Synthphobic"
desc = "You know, deep down, that synthetics cannot be trusted, and so you are always on guard whenever you see one wandering around. No one knows how a Positronic's mind works, \
Drones are just waiting for the right time for Emergence, and the poor brains trapped in the cage of Man Machine Interfaces are now soulless, despite being unaware of it. None \
can be trusted."
/datum/trait/modifier/mental/xenophobe
name = "Xenophobic"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
mutually_exclusive = list(
/datum/trait/modifier/mental/humanphobe,
/datum/trait/modifier/mental/skrellphobe,
/datum/trait/modifier/mental/tajaraphobe,
/datum/trait/modifier/mental/unathiphobe,
/datum/trait/modifier/mental/teshariphobe,
/datum/trait/modifier/mental/prometheanphobe
)
/datum/trait/modifier/mental/humanphobe
name = "Human-phobic"
desc = "Boilerplate racism for monkeys goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/skrellphobe
name = "Skrell-phobic"
desc = "Boilerplate racism for squid goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/tajaraphobe
name = "Tajara-phobic"
desc = "Boilerplate racism for cats goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/unathiphobe
name = "Unathi-phobic"
desc = "Boilerplate racism for lizards goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
// Not sure why anyone would hate/fear these guys but for the sake of completeness here we are.
/datum/trait/modifier/mental/dionaphobe
name = "Diona-phobic"
desc = "Boilerplate racism for trees goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/teshariphobe
name = "Teshari-phobic"
desc = "Boilerplate racism for birds goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/prometheanphobe
name = "Promethean-phobic"
desc = "Boilerplate racism for jellos goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
*/
@@ -0,0 +1,196 @@
var/list/trait_datums = list() // Assoc list using name = instance. Traits are saved as a list of strings.
var/list/trait_type_to_ref = list() // Similar to above but uses paths, which is more reliable but more risky to save.
var/list/trait_categories = list() // The categories available for the trait menu.
/hook/startup/proc/populate_trait_list()
//create a list of trait datums
for(var/trait_type in typesof(/datum/trait) - list(/datum/trait, /datum/trait/modifier))
var/datum/trait/T = new trait_type
if(!T.name)
error("Trait Menu - Missing name: [T.type]")
continue
if(!T.category)
error("Trait Menu - Missing category: [T.type]")
continue
T.desc = T.generate_desc()
trait_datums[T.name] = T
trait_type_to_ref[T.type] = T
if(!(T.category in trait_categories))
trait_categories += T.category
return 1
/datum/category_item/player_setup_item/traits
name = "Quirks" //VOREStation Edit
sort_order = 1
var/current_tab = "Physical"
/datum/category_item/player_setup_item/traits/load_character(var/savefile/S)
S["traits"] >> pref.traits
/datum/category_item/player_setup_item/traits/save_character(var/savefile/S)
S["traits"] << pref.traits
/datum/category_item/player_setup_item/traits/content()
. = list()
. += "<table align = 'center' width = 100%>"
. += "<tr><td colspan=3><hr></td></tr>"
. += "<tr><td colspan=3><b><center>Traits</center></b></td></tr>"
. += "<tr><td colspan=3><hr></td></tr>"
. += "<tr><td colspan=3><center>"
var/firstcat = 1
for(var/category in trait_categories)
if(firstcat)
firstcat = 0
else
. += " |"
if(category == current_tab)
. += " <span class='linkOn'>[category]</span> "
else
. += " <a href='?src=\ref[src];select_category=[category]'>[category]</a> "
. += "</center></td></tr>"
for(var/trait_name in trait_datums)
var/datum/trait/T = trait_datums[trait_name]
if(T.category != current_tab)
continue
var/ticked = (T.name in pref.traits)
var/style_class
if(!T.validate(pref.traits, src))
style_class = "linkOff"
else if(ticked)
style_class = "linkOn"
. += "<tr style='vertical-align:top;'><td width=25%><div align='center'><a style='white-space:normal;' [style_class ? "class='[style_class]' " : ""]href='?src=\ref[src];toggle_trait=[html_encode(T.name)]'>[T.name]</a></div></td>"
// . += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
var/invalidity = T.test_for_invalidity(src)
var/conflicts = T.test_for_trait_conflict(pref.traits)
var/invalid = ""
if(invalidity)
invalid += "[invalidity] "
if(conflicts)
invalid += "This trait is mutually exclusive with [conflicts]."
. += "<td width = 75%><font size=2><i>[T.desc]</i>\
[invalid ? "<font color='#FF0000'><br>Cannot take trait. Reason: [invalid]</font>":""]</font></td></tr>"
// if(ticked)
// . += "<tr><td colspan=3>"
// for(var/datum/gear_tweak/tweak in G.gear_tweaks)
// . += " <a href='?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
// . += "</td></tr>"
. += "</table>"
. = jointext(., null)
/datum/category_item/player_setup_item/traits/sanitize_character()
var/mob/preference_mob = preference_mob()
if(!islist(pref.traits))
pref.traits = list()
for(var/trait_name in pref.traits)
if(!(trait_name in trait_datums))
pref.traits -= trait_name
for(var/trait_name in pref.traits)
if(!trait_datums[trait_name])
preference_mob << "<span class='warning'>You cannot have more than one of trait: [trait_name]</span>"
pref.traits -= trait_name
else
var/datum/trait/T = trait_datums[trait_name]
var/invalidity = T.test_for_invalidity(src)
if(invalidity)
pref.traits -= trait_name
preference_mob << "<span class='warning'>You cannot take the [trait_name] trait. Reason: [invalidity]</span>"
var/conflicts = T.test_for_trait_conflict(pref.traits)
if(conflicts)
pref.traits -= trait_name
to_chat(preference_mob, "<span class='warning'>The [trait_name] trait is mutually exclusive with [conflicts].</span>")
/datum/category_item/player_setup_item/traits/OnTopic(href, href_list, user)
if(href_list["toggle_trait"])
var/datum/trait/T = trait_datums[href_list["toggle_trait"]]
if(T.name in pref.traits)
pref.traits -= T.name
else
var/invalidity = T.test_for_invalidity(src)
if(invalidity)
to_chat(user, "<span class='warning'>You cannot take the [T.name] trait. Reason: [invalidity]</span>")
return TOPIC_NOACTION
var/conflicts = T.test_for_trait_conflict(pref.traits)
if(conflicts)
to_chat(user, "<span class='warning'>The [T.name] trait is mutually exclusive with [conflicts].</span>")
return TOPIC_NOACTION
pref.traits += T.name
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["select_category"])
current_tab = href_list["select_category"]
return TOPIC_REFRESH
return ..()
/datum/trait
var/name = null // Name to show on UI
var/desc = null // Description of what it does, also shown on UI.
var/list/mutually_exclusive = list() // List of trait types which cannot be taken alongside this trait.
var/category = null // What section to place this trait inside.
// Applies effects to the newly spawned mob.
/datum/trait/proc/apply_trait_post_spawn(var/mob/living/L)
return
// Used to forbid a trait based on certain criteria (e.g. if they are an FBP).
// It receives the player_setup_item datum since some reasons for being invalid depend on the currently loaded preferences.
// Returns a string explaining why the trait is invalid. Returns null if valid.
/datum/trait/proc/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
return null
// Checks mutually_exclusive. current_traits needs to be a list of strings.
// Returns null if everything is well, similar to the above proc. Otherwise returns an english_list() of conflicting traits.
/datum/trait/proc/test_for_trait_conflict(var/list/current_traits)
var/list/conflicts = list()
var/result
if(mutually_exclusive.len)
for(var/trait_name in current_traits)
var/datum/trait/T = trait_datums[trait_name]
if(T.type in mutually_exclusive)
conflicts.Add(T.name)
if(conflicts.len)
result = english_list(conflicts)
return result
// Similar to above, but uses the above two procs, in one place.
// Returns TRUE is everything is well.
/datum/trait/proc/validate(var/list/current_traits, var/datum/category_item/player_setup_item/traits/setup)
if(test_for_invalidity(setup))
return FALSE
if(test_for_trait_conflict(current_traits))
return FALSE
return TRUE
// Creates a description, if one doesn't exist.
// This one is for inheritence, and so doesn't do anything.
/datum/trait/proc/generate_desc()
return desc
/mob/living/proc/apply_traits()
if(!mind || !mind.traits || !mind.traits.len)
return
for(var/trait in mind.traits)
var/datum/trait/T = trait_datums[trait]
if(istype(T))
T.apply_trait_post_spawn(src)