Merge pull request #6663 from Citadel-Station-13/upstream-merge-37646

[MIRROR] Renames trait datums/character traits to quirks to differentiate them from the other trait system in the code
This commit is contained in:
LetterJay
2018-05-15 00:47:59 -05:00
committed by GitHub
22 changed files with 331 additions and 296 deletions
+1 -1
View File
@@ -258,7 +258,7 @@
// Roundstart trait system // Roundstart trait system
#define MAX_TRAITS 6 //The maximum amount of traits one character can have at roundstart #define MAX_QUIRKS 6 //The maximum amount of quirks one character can have at roundstart
// AI Toggles // AI Toggles
#define AI_CAMERA_LUMINOSITY 5 #define AI_CAMERA_LUMINOSITY 5
+1 -1
View File
@@ -56,7 +56,7 @@
#define INIT_ORDER_RESEARCH 14 #define INIT_ORDER_RESEARCH 14
#define INIT_ORDER_EVENTS 13 #define INIT_ORDER_EVENTS 13
#define INIT_ORDER_JOBS 12 #define INIT_ORDER_JOBS 12
#define INIT_ORDER_TRAITS 11 #define INIT_ORDER_QUIRKS 11
#define INIT_ORDER_TICKER 10 #define INIT_ORDER_TICKER 10
#define INIT_ORDER_MAPPING 9 #define INIT_ORDER_MAPPING 9
#define INIT_ORDER_NETWORKS 8 #define INIT_ORDER_NETWORKS 8
@@ -0,0 +1,34 @@
//Used to process and handle roundstart quirks
// - Quirk strings are used for faster checking in code
// - Quirk datums are stored and hold different effects, as well as being a vector for applying trait string
PROCESSING_SUBSYSTEM_DEF(quirks)
name = "Quirks"
init_order = INIT_ORDER_QUIRKS
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/
var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad
var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)
SetupQuirks()
..()
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
for(var/V in subtypesof(/datum/quirk))
var/datum/quirk/T = V
quirks[initial(T.name)] = T
quirk_points[initial(T.name)] = initial(T.value)
/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects)
GenerateQuirks(cli)
for(var/V in cli.prefs.character_quirks)
user.add_quirk(V, spawn_effects)
/datum/controller/subsystem/processing/quirks/proc/GenerateQuirks(client/user)
if(user.prefs.character_quirks.len)
return
user.prefs.character_quirks = user.prefs.all_quirks
+1 -1
View File
@@ -391,7 +391,7 @@ SUBSYSTEM_DEF(ticker)
if(player.mind.assigned_role != player.mind.special_role) if(player.mind.assigned_role != player.mind.special_role)
SSjob.EquipRank(N, player.mind.assigned_role, 0) SSjob.EquipRank(N, player.mind.assigned_role, 0)
if(CONFIG_GET(flag/roundstart_traits)) if(CONFIG_GET(flag/roundstart_traits))
SStraits.AssignTraits(player, N.client, TRUE) SSquirks.AssignQuirks(player, N.client, TRUE)
CHECK_TICK CHECK_TICK
if(captainless) if(captainless)
for(var/mob/dead/new_player/N in GLOB.player_list) for(var/mob/dead/new_player/N in GLOB.player_list)
@@ -1,94 +1,94 @@
//every trait in this folder should be coded around being applied on spawn //every quirk in this folder should be coded around being applied on spawn
//these are NOT "mob traits" like GOTTAGOFAST, but exist as a medium to apply them and other different effects //these are NOT "mob quirks" like GOTTAGOFAST, but exist as a medium to apply them and other different effects
/datum/trait /datum/quirk
var/name = "Test Trait" var/name = "Test Quirk"
var/desc = "This is a test trait." var/desc = "This is a test quirk."
var/value = 0 var/value = 0
var/human_only = TRUE var/human_only = TRUE
var/gain_text var/gain_text
var/lose_text var/lose_text
var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented
var/mood_trait = FALSE //if true, this trait affects mood and is unavailable if moodlets are disabled var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
var/mob_trait //if applicable, apply and remove this mob trait var/mob_trait //if applicable, apply and remove this mob trait
var/mob/living/trait_holder var/mob/living/quirk_holder
/datum/trait/New(mob/living/trait_mob, spawn_effects) /datum/quirk/New(mob/living/quirk_mob, spawn_effects)
..() ..()
if(!trait_mob || (human_only && !ishuman(trait_mob)) || trait_mob.has_trait_datum(type)) if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
qdel(src) qdel(src)
trait_holder = trait_mob quirk_holder = quirk_mob
SStraits.trait_objects += src SSquirks.quirk_objects += src
to_chat(trait_holder, gain_text) to_chat(quirk_holder, gain_text)
trait_holder.roundstart_traits += src quirk_holder.roundstart_quirks += src
if(mob_trait) if(mob_trait)
trait_holder.add_trait(mob_trait, ROUNDSTART_TRAIT) quirk_holder.add_trait(mob_trait, ROUNDSTART_TRAIT)
START_PROCESSING(SStraits, src) START_PROCESSING(SSquirks, src)
add() add()
if(spawn_effects) if(spawn_effects)
on_spawn() on_spawn()
addtimer(CALLBACK(src, .proc/post_add), 30) addtimer(CALLBACK(src, .proc/post_add), 30)
/datum/trait/Destroy() /datum/quirk/Destroy()
STOP_PROCESSING(SStraits, src) STOP_PROCESSING(SSquirks, src)
remove() remove()
if(trait_holder) if(quirk_holder)
to_chat(trait_holder, lose_text) to_chat(quirk_holder, lose_text)
trait_holder.roundstart_traits -= src quirk_holder.roundstart_quirks -= src
if(mob_trait) if(mob_trait)
trait_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE) quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE)
SStraits.trait_objects -= src SSquirks.quirk_objects -= src
return ..() return ..()
/datum/trait/proc/transfer_mob(mob/living/to_mob) /datum/quirk/proc/transfer_mob(mob/living/to_mob)
trait_holder.roundstart_traits -= src quirk_holder.roundstart_quirks -= src
to_mob.roundstart_traits += src to_mob.roundstart_quirks += src
if(mob_trait) if(mob_trait)
trait_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT) quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT)
to_mob.add_trait(mob_trait, ROUNDSTART_TRAIT) to_mob.add_trait(mob_trait, ROUNDSTART_TRAIT)
trait_holder = to_mob quirk_holder = to_mob
on_transfer() on_transfer()
/datum/trait/proc/add() //special "on add" effects /datum/quirk/proc/add() //special "on add" effects
/datum/trait/proc/on_spawn() //these should only trigger when the character is being created for the first time, i.e. roundstart/latejoin /datum/quirk/proc/on_spawn() //these should only trigger when the character is being created for the first time, i.e. roundstart/latejoin
/datum/trait/proc/remove() //special "on remove" effects /datum/quirk/proc/remove() //special "on remove" effects
/datum/trait/proc/on_process() //process() has some special checks, so this is the actual process /datum/quirk/proc/on_process() //process() has some special checks, so this is the actual process
/datum/trait/proc/post_add() //for text, disclaimers etc. given after you spawn in with the trait /datum/quirk/proc/post_add() //for text, disclaimers etc. given after you spawn in with the trait
/datum/trait/proc/on_transfer() //code called when the trait is transferred to a new mob /datum/quirk/proc/on_transfer() //code called when the trait is transferred to a new mob
/datum/trait/process() /datum/quirk/process()
if(QDELETED(trait_holder)) if(QDELETED(quirk_holder))
trait_holder = null quirk_holder = null
qdel(src) qdel(src)
return return
if(trait_holder.stat == DEAD) if(quirk_holder.stat == DEAD)
return return
on_process() on_process()
/mob/living/proc/get_trait_string(medical) //helper string. gets a string of all the traits the mob has /mob/living/proc/get_trait_string(medical) //helper string. gets a string of all the traits the mob has
var/list/dat = list() var/list/dat = list()
if(!medical) if(!medical)
for(var/V in roundstart_traits) for(var/V in roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
dat += T.name dat += T.name
if(!dat.len) if(!dat.len)
return "None" return "None"
return dat.Join(", ") return dat.Join(", ")
else else
for(var/V in roundstart_traits) for(var/V in roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
dat += T.medical_record_text dat += T.medical_record_text
if(!dat.len) if(!dat.len)
return "None" return "None"
return dat.Join("<br>") return dat.Join("<br>")
/mob/living/proc/cleanse_trait_datums() //removes all trait datums /mob/living/proc/cleanse_trait_datums() //removes all trait datums
for(var/V in roundstart_traits) for(var/V in roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
qdel(T) qdel(T)
/mob/living/proc/transfer_trait_datums(mob/living/to_mob) /mob/living/proc/transfer_trait_datums(mob/living/to_mob)
for(var/V in roundstart_traits) for(var/V in roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
T.transfer_mob(to_mob) T.transfer_mob(to_mob)
/* /*
@@ -96,7 +96,7 @@
Commented version of Nearsighted to help you add your own traits Commented version of Nearsighted to help you add your own traits
Use this as a guideline Use this as a guideline
/datum/trait/nearsighted /datum/quirk/nearsighted
name = "Nearsighted" name = "Nearsighted"
///The trait's name ///The trait's name
@@ -116,8 +116,8 @@ Use this as a guideline
medical_record_text = "Subject has permanent nearsightedness." medical_record_text = "Subject has permanent nearsightedness."
///These three are self-explanatory ///These three are self-explanatory
/datum/trait/nearsighted/on_spawn() /datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H)) var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
H.put_in_hands(glasses) H.put_in_hands(glasses)
H.equip_to_slot(glasses, slot_glasses) H.equip_to_slot(glasses, slot_glasses)
+18 -18
View File
@@ -1,7 +1,7 @@
//predominantly positive traits //predominantly positive traits
//this file is named weirdly so that positive traits are listed above negative ones //this file is named weirdly so that positive traits are listed above negative ones
/datum/trait/alcohol_tolerance /datum/quirk/alcohol_tolerance
name = "Alcohol Tolerance" name = "Alcohol Tolerance"
desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol." desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol."
value = 1 value = 1
@@ -11,25 +11,25 @@
/datum/trait/apathetic /datum/quirk/apathetic
name = "Apathetic" name = "Apathetic"
desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess." desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
value = 1 value = 1
mood_trait = TRUE mood_quirk = TRUE
/datum/trait/apathetic/add() /datum/quirk/apathetic/add()
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder) GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
if(mood) if(mood)
mood.mood_modifier = 0.8 mood.mood_modifier = 0.8
/datum/trait/apathetic/remove() /datum/quirk/apathetic/remove()
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder) GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
if(mood) if(mood)
mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers. mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers.
/datum/trait/freerunning /datum/quirk/freerunning
name = "Freerunning" name = "Freerunning"
desc = "You're great at quick moves! You can climb tables more quickly." desc = "You're great at quick moves! You can climb tables more quickly."
value = 2 value = 2
@@ -39,16 +39,16 @@
/datum/trait/jolly /datum/quirk/jolly
name = "Jolly" name = "Jolly"
desc = "You sometimes just feel happy, for no reason at all." desc = "You sometimes just feel happy, for no reason at all."
value = 1 value = 1
mob_trait = TRAIT_JOLLY mob_trait = TRAIT_JOLLY
mood_trait = TRUE mood_quirk = TRUE
/datum/trait/light_step /datum/quirk/light_step
name = "Light Step" name = "Light Step"
desc = "You walk with a gentle step, making stepping on sharp objects quieter and less painful." desc = "You walk with a gentle step, making stepping on sharp objects quieter and less painful."
value = 1 value = 1
@@ -58,7 +58,7 @@
/datum/trait/night_vision /datum/quirk/night_vision
name = "Night Vision" name = "Night Vision"
desc = "You can see slightly more clearly in full darkness than most people." desc = "You can see slightly more clearly in full darkness than most people."
value = 1 value = 1
@@ -66,8 +66,8 @@
gain_text = "<span class='notice'>The shadows seem a little less dark.</span>" gain_text = "<span class='notice'>The shadows seem a little less dark.</span>"
lose_text = "<span class='danger'>Everything seems a little darker.</span>" lose_text = "<span class='danger'>Everything seems a little darker.</span>"
/datum/trait/night_vision/on_spawn() /datum/quirk/night_vision/on_spawn()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/organ/eyes/eyes = H.getorgan(/obj/item/organ/eyes) var/obj/item/organ/eyes/eyes = H.getorgan(/obj/item/organ/eyes)
if(!eyes || eyes.lighting_alpha) if(!eyes || eyes.lighting_alpha)
return return
@@ -75,7 +75,7 @@
/datum/trait/selfaware /datum/quirk/selfaware
name = "Self-Aware" name = "Self-Aware"
desc = "You know your body well, and can accurately assess the extent of your wounds." desc = "You know your body well, and can accurately assess the extent of your wounds."
value = 2 value = 2
@@ -83,7 +83,7 @@
/datum/trait/skittish /datum/quirk/skittish
name = "Skittish" name = "Skittish"
desc = "You can conceal yourself in danger. Ctrl-shift-click a closed locker to jump into it, as long as you have access." desc = "You can conceal yourself in danger. Ctrl-shift-click a closed locker to jump into it, as long as you have access."
value = 2 value = 2
@@ -91,7 +91,7 @@
/datum/trait/spiritual /datum/quirk/spiritual
name = "Spiritual" name = "Spiritual"
desc = "You're in tune with the gods, and your prayers may be more likely to be heard. Or not." desc = "You're in tune with the gods, and your prayers may be more likely to be heard. Or not."
value = 1 value = 1
@@ -101,7 +101,7 @@
/datum/trait/voracious /datum/quirk/voracious
name = "Voracious" name = "Voracious"
desc = "Nothing gets between you and your food. You eat twice as fast as everyone else!" desc = "Nothing gets between you and your food. You eat twice as fast as everyone else!"
value = 1 value = 1
+67 -67
View File
@@ -1,6 +1,6 @@
//predominantly negative traits //predominantly negative traits
/datum/trait/blooddeficiency /datum/quirk/blooddeficiency
name = "Acute Blood Deficiency" name = "Acute Blood Deficiency"
desc = "Your body can't produce enough blood to sustain itself." desc = "Your body can't produce enough blood to sustain itself."
value = -2 value = -2
@@ -8,12 +8,12 @@
lose_text = "<span class='notice'>You feel vigorous again.</span>" lose_text = "<span class='notice'>You feel vigorous again.</span>"
medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood." medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
/datum/trait/blooddeficiency/on_process() /datum/quirk/blooddeficiency/on_process()
trait_holder.blood_volume -= 0.275 quirk_holder.blood_volume -= 0.275
/datum/trait/depression /datum/quirk/depression
name = "Depression" name = "Depression"
desc = "You sometimes just hate life." desc = "You sometimes just hate life."
mob_trait = TRAIT_DEPRESSION mob_trait = TRAIT_DEPRESSION
@@ -21,22 +21,22 @@
gain_text = "<span class='danger'>You start feeling depressed.</span>" gain_text = "<span class='danger'>You start feeling depressed.</span>"
lose_text = "<span class='notice'>You no longer feel depressed.</span>" //if only it were that easy! lose_text = "<span class='notice'>You no longer feel depressed.</span>" //if only it were that easy!
medical_record_text = "Patient has a severe mood disorder causing them to experience sudden moments of sadness." medical_record_text = "Patient has a severe mood disorder causing them to experience sudden moments of sadness."
mood_trait = TRUE mood_quirk = TRUE
/datum/trait/family_heirloom /datum/quirk/family_heirloom
name = "Family Heirloom" name = "Family Heirloom"
desc = "You are the current owner of an heirloom. passed down for generations. You have to keep it safe!" desc = "You are the current owner of an heirloom. passed down for generations. You have to keep it safe!"
value = -1 value = -1
mood_trait = TRUE mood_quirk = TRUE
var/obj/item/heirloom var/obj/item/heirloom
var/where_text var/where_text
/datum/trait/family_heirloom/on_spawn() /datum/quirk/family_heirloom/on_spawn()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/heirloom_type var/obj/item/heirloom_type
switch(trait_holder.mind.assigned_role) switch(quirk_holder.mind.assigned_role)
if("Clown") if("Clown")
heirloom_type = /obj/item/bikehorn/golden heirloom_type = /obj/item/bikehorn/golden
if("Mime") if("Mime")
@@ -56,7 +56,7 @@
/obj/item/toy/cards/deck, /obj/item/toy/cards/deck,
/obj/item/lighter, /obj/item/lighter,
/obj/item/dice/d20) /obj/item/dice/d20)
heirloom = new heirloom_type(get_turf(trait_holder)) heirloom = new heirloom_type(get_turf(quirk_holder))
var/list/slots = list( var/list/slots = list(
"in your backpack" = slot_in_backpack, "in your backpack" = slot_in_backpack,
"in your left pocket" = slot_l_store, "in your left pocket" = slot_l_store,
@@ -69,22 +69,22 @@
H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H) H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H)
where_text = "<span class='boldnotice'>There is a precious family [heirloom.name] [where], passed down from generation to generation. Keep it safe!</span>" where_text = "<span class='boldnotice'>There is a precious family [heirloom.name] [where], passed down from generation to generation. Keep it safe!</span>"
/datum/trait/family_heirloom/post_add() /datum/quirk/family_heirloom/post_add()
to_chat(trait_holder, where_text) to_chat(quirk_holder, where_text)
var/list/family_name = splittext(trait_holder.real_name, " ") var/list/family_name = splittext(quirk_holder.real_name, " ")
heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]" heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]"
/datum/trait/family_heirloom/on_process() /datum/quirk/family_heirloom/on_process()
if(heirloom in trait_holder.GetAllContents()) if(heirloom in quirk_holder.GetAllContents())
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing") quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom) quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
else else
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom") quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom")
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing) quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
/datum/trait/heavy_sleeper /datum/quirk/heavy_sleeper
name = "Heavy Sleeper" name = "Heavy Sleeper"
desc = "You sleep like a rock! Whenever you're put to sleep, you sleep for a little bit longer." desc = "You sleep like a rock! Whenever you're put to sleep, you sleep for a little bit longer."
value = -1 value = -1
@@ -93,7 +93,7 @@
lose_text = "<span class='notice'>You feel awake again.</span>" lose_text = "<span class='notice'>You feel awake again.</span>"
medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up." medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up."
/datum/trait/brainproblems /datum/quirk/brainproblems
name = "Brain Tumor" name = "Brain Tumor"
desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!" desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!"
value = -3 value = -3
@@ -101,12 +101,12 @@
lose_text = "<span class='notice'>You feel wrinkled again.</span>" lose_text = "<span class='notice'>You feel wrinkled again.</span>"
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death." medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
/datum/trait/brainproblems/on_process() /datum/quirk/brainproblems/on_process()
trait_holder.adjustBrainLoss(0.2) quirk_holder.adjustBrainLoss(0.2)
/datum/trait/nearsighted //t. errorage /datum/quirk/nearsighted //t. errorage
name = "Nearsighted" name = "Nearsighted"
desc = "You are nearsighted without prescription glasses, but spawn with a pair." desc = "You are nearsighted without prescription glasses, but spawn with a pair."
value = -1 value = -1
@@ -114,11 +114,11 @@
lose_text = "<span class='notice'>You start seeing faraway things normally again.</span>" lose_text = "<span class='notice'>You start seeing faraway things normally again.</span>"
medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness." medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness."
/datum/trait/nearsighted/add() /datum/quirk/nearsighted/add()
trait_holder.become_nearsighted(ROUNDSTART_TRAIT) quirk_holder.become_nearsighted(ROUNDSTART_TRAIT)
/datum/trait/nearsighted/on_spawn() /datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H)) var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
H.put_in_hands(glasses) H.put_in_hands(glasses)
H.equip_to_slot(glasses, slot_glasses) H.equip_to_slot(glasses, slot_glasses)
@@ -126,28 +126,28 @@
/datum/trait/nyctophobia /datum/quirk/nyctophobia
name = "Nyctophobia" name = "Nyctophobia"
desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctually act careful, and constantly feel a sense of dread." desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctually act careful, and constantly feel a sense of dread."
value = -1 value = -1
/datum/trait/nyctophobia/on_process() /datum/quirk/nyctophobia/on_process()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
if(H.dna.species.id in list("shadow", "nightmare")) if(H.dna.species.id in list("shadow", "nightmare"))
return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese
var/turf/T = get_turf(trait_holder) var/turf/T = get_turf(quirk_holder)
var/lums = T.get_lumcount() var/lums = T.get_lumcount()
if(lums <= 0.2) if(lums <= 0.2)
if(trait_holder.m_intent == MOVE_INTENT_RUN) if(quirk_holder.m_intent == MOVE_INTENT_RUN)
to_chat(trait_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>") to_chat(quirk_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
trait_holder.toggle_move_intent() quirk_holder.toggle_move_intent()
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia) quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
else else
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
/datum/trait/nonviolent /datum/quirk/nonviolent
name = "Pacifist" name = "Pacifist"
desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone." desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
value = -2 value = -2
@@ -156,14 +156,14 @@
lose_text = "<span class='notice'>You think you can defend yourself again.</span>" lose_text = "<span class='notice'>You think you can defend yourself again.</span>"
medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm." medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
/datum/trait/nonviolent/on_process() /datum/quirk/nonviolent/on_process()
if(trait_holder.mind && LAZYLEN(trait_holder.mind.antag_datums)) if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(trait_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>") to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
qdel(src) qdel(src)
/datum/trait/poor_aim /datum/quirk/poor_aim
name = "Poor Aim" name = "Poor Aim"
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out." desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
value = -1 value = -1
@@ -172,7 +172,7 @@
/datum/trait/prosopagnosia /datum/quirk/prosopagnosia
name = "Prosopagnosia" name = "Prosopagnosia"
desc = "You have a mental disorder that prevents you from being able to recognize faces at all." desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
value = -1 value = -1
@@ -181,41 +181,41 @@
/datum/trait/prosthetic_limb /datum/quirk/prosthetic_limb
name = "Prosthetic Limb" name = "Prosthetic Limb"
desc = "An accident caused you to lose one of your limbs. Because of this, you now have a random prosthetic!" desc = "An accident caused you to lose one of your limbs. Because of this, you now have a random prosthetic!"
value = -1 value = -1
var/slot_string = "limb" var/slot_string = "limb"
/datum/trait/prosthetic_limb/on_spawn() /datum/quirk/prosthetic_limb/on_spawn()
var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot) var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
var/obj/item/bodypart/prosthetic var/obj/item/bodypart/prosthetic
switch(limb_slot) switch(limb_slot)
if(BODY_ZONE_L_ARM) if(BODY_ZONE_L_ARM)
prosthetic = new/obj/item/bodypart/l_arm/robot/surplus(trait_holder) prosthetic = new/obj/item/bodypart/l_arm/robot/surplus(quirk_holder)
slot_string = "left arm" slot_string = "left arm"
if(BODY_ZONE_R_ARM) if(BODY_ZONE_R_ARM)
prosthetic = new/obj/item/bodypart/r_arm/robot/surplus(trait_holder) prosthetic = new/obj/item/bodypart/r_arm/robot/surplus(quirk_holder)
slot_string = "right arm" slot_string = "right arm"
if(BODY_ZONE_L_LEG) if(BODY_ZONE_L_LEG)
prosthetic = new/obj/item/bodypart/l_leg/robot/surplus(trait_holder) prosthetic = new/obj/item/bodypart/l_leg/robot/surplus(quirk_holder)
slot_string = "left leg" slot_string = "left leg"
if(BODY_ZONE_R_LEG) if(BODY_ZONE_R_LEG)
prosthetic = new/obj/item/bodypart/r_leg/robot/surplus(trait_holder) prosthetic = new/obj/item/bodypart/r_leg/robot/surplus(quirk_holder)
slot_string = "right leg" slot_string = "right leg"
prosthetic.replace_limb(H) prosthetic.replace_limb(H)
qdel(old_part) qdel(old_part)
H.regenerate_icons() H.regenerate_icons()
/datum/trait/prosthetic_limb/post_add() /datum/quirk/prosthetic_limb/post_add()
to_chat(trait_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \ to_chat(quirk_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.</span>") you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.</span>")
/datum/trait/insanity /datum/quirk/insanity
name = "Reality Dissociation Syndrome" name = "Reality Dissociation Syndrome"
desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. <b>This is not a license to grief.</b>" desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. <b>This is not a license to grief.</b>"
value = -2 value = -2
@@ -224,32 +224,32 @@
lose_text = "<span class='notice'>You feel in tune with the world again.</span>" lose_text = "<span class='notice'>You feel in tune with the world again.</span>"
medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations." medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
/datum/trait/insanity/on_process() /datum/quirk/insanity/on_process()
if(trait_holder.reagents.has_reagent("mindbreaker")) if(quirk_holder.reagents.has_reagent("mindbreaker"))
trait_holder.hallucination = 0 quirk_holder.hallucination = 0
return return
if(prob(2)) //we'll all be mad soon enough if(prob(2)) //we'll all be mad soon enough
madness() madness()
/datum/trait/insanity/proc/madness(mad_fools) /datum/quirk/insanity/proc/madness(mad_fools)
set waitfor = FALSE set waitfor = FALSE
if(!mad_fools) if(!mad_fools)
mad_fools = prob(20) mad_fools = prob(20)
if(mad_fools) if(mad_fools)
var/hallucination_type = pick(subtypesof(/datum/hallucination/rds)) var/hallucination_type = pick(subtypesof(/datum/hallucination/rds))
new hallucination_type (trait_holder, FALSE) new hallucination_type (quirk_holder, FALSE)
else else
trait_holder.hallucination += rand(10, 50) quirk_holder.hallucination += rand(10, 50)
/datum/trait/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have /datum/quirk/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have
if(!trait_holder.mind || trait_holder.mind.special_role) if(!quirk_holder.mind || quirk_holder.mind.special_role)
return return
to_chat(trait_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \ to_chat(quirk_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>") the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>")
/datum/trait/social_anxiety /datum/quirk/social_anxiety
name = "Social Anxiety" name = "Social Anxiety"
desc = "Talking to people is very difficult for you, and you often stutter or even lock up." desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
value = -1 value = -1
@@ -258,12 +258,12 @@
medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them." medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
var/dumb_thing = TRUE var/dumb_thing = TRUE
/datum/trait/social_anxiety/on_process() /datum/quirk/social_anxiety/on_process()
var/nearby_people = 0 var/nearby_people = 0
for(var/mob/living/carbon/human/H in view(5, trait_holder)) for(var/mob/living/carbon/human/H in view(5, quirk_holder))
if(H.client) if(H.client)
nearby_people++ nearby_people++
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
if(prob(2 + nearby_people)) if(prob(2 + nearby_people))
H.stuttering = max(3, H.stuttering) H.stuttering = max(3, H.stuttering)
else if(prob(min(3, nearby_people)) && !H.silent) else if(prob(min(3, nearby_people)) && !H.silent)
+25 -25
View File
@@ -1,7 +1,7 @@
//traits with no real impact that can be taken freely //traits with no real impact that can be taken freely
//MAKE SURE THESE DO NOT MAJORLY IMPACT GAMEPLAY. those should be positive or negative traits. //MAKE SURE THESE DO NOT MAJORLY IMPACT GAMEPLAY. those should be positive or negative traits.
/datum/trait/no_taste /datum/quirk/no_taste
name = "Ageusia" name = "Ageusia"
desc = "You can't taste anything! Toxic food will still poison you." desc = "You can't taste anything! Toxic food will still poison you."
value = 0 value = 0
@@ -12,75 +12,75 @@
/datum/trait/pineapple_liker /datum/quirk/pineapple_liker
name = "Ananas Affinity" name = "Ananas Affinity"
desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!" desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
value = 0 value = 0
gain_text = "<span class='notice'>You feel an intense craving for pineapple.</span>" gain_text = "<span class='notice'>You feel an intense craving for pineapple.</span>"
lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>" lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>"
/datum/trait/pineapple_liker/add() /datum/quirk/pineapple_liker/add()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
species.liked_food |= PINEAPPLE species.liked_food |= PINEAPPLE
/datum/trait/pineapple_liker/remove() /datum/quirk/pineapple_liker/remove()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
species.liked_food &= ~PINEAPPLE species.liked_food &= ~PINEAPPLE
/datum/trait/pineapple_hater /datum/quirk/pineapple_hater
name = "Ananas Aversion" name = "Ananas Aversion"
desc = "You find yourself greatly detesting fruits of the ananas genus. Serious, how the hell can anyone say these things are good? And what kind of madman would even dare putting it on a pizza!?" desc = "You find yourself greatly detesting fruits of the ananas genus. Serious, how the hell can anyone say these things are good? And what kind of madman would even dare putting it on a pizza!?"
value = 0 value = 0
gain_text = "<span class='notice'>You find yourself pondering what kind of idiot actually enjoys pineapples...</span>" gain_text = "<span class='notice'>You find yourself pondering what kind of idiot actually enjoys pineapples...</span>"
lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>" lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>"
/datum/trait/pineapple_hater/add() /datum/quirk/pineapple_hater/add()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
species.disliked_food |= PINEAPPLE species.disliked_food |= PINEAPPLE
/datum/trait/pineapple_hater/remove() /datum/quirk/pineapple_hater/remove()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
species.disliked_food &= ~PINEAPPLE species.disliked_food &= ~PINEAPPLE
/datum/trait/deviant_tastes /datum/quirk/deviant_tastes
name = "Deviant Tastes" name = "Deviant Tastes"
desc = "You dislike food that most people enjoy, and find delicious what they don't." desc = "You dislike food that most people enjoy, and find delicious what they don't."
value = 0 value = 0
gain_text = "<span class='notice'>You start craving something that tastes strange.</span>" gain_text = "<span class='notice'>You start craving something that tastes strange.</span>"
lose_text = "<span class='notice'>You feel like eating normal food again.</span>" lose_text = "<span class='notice'>You feel like eating normal food again.</span>"
/datum/trait/deviant_tastes/add() /datum/quirk/deviant_tastes/add()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
var/liked = species.liked_food var/liked = species.liked_food
species.liked_food = species.disliked_food species.liked_food = species.disliked_food
species.disliked_food = liked species.disliked_food = liked
/datum/trait/deviant_tastes/remove() /datum/quirk/deviant_tastes/remove()
var/mob/living/carbon/human/H = trait_holder var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species var/datum/species/species = H.dna.species
species.liked_food = initial(species.liked_food) species.liked_food = initial(species.liked_food)
species.disliked_food = initial(species.disliked_food) species.disliked_food = initial(species.disliked_food)
/datum/trait/monochromatic /datum/quirk/monochromatic
name = "Monochromacy" name = "Monochromacy"
desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites." desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
value = 0 value = 0
medical_record_text = "Patient is afflicted with almost complete color blindness." medical_record_text = "Patient is afflicted with almost complete color blindness."
/datum/trait/monochromatic/add() /datum/quirk/monochromatic/add()
trait_holder.add_client_colour(/datum/client_colour/monochrome) quirk_holder.add_client_colour(/datum/client_colour/monochrome)
/datum/trait/monochromatic/post_add() /datum/quirk/monochromatic/post_add()
if(trait_holder.mind.assigned_role == "Detective") if(quirk_holder.mind.assigned_role == "Detective")
to_chat(trait_holder, "<span class='boldannounce'>Mmm. Nothing's ever clear on this station. It's all shades of gray...</span>") to_chat(quirk_holder, "<span class='boldannounce'>Mmm. Nothing's ever clear on this station. It's all shades of gray...</span>")
trait_holder.playsound_local(trait_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE) quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
/datum/trait/monochromatic/remove() /datum/quirk/monochromatic/remove()
trait_holder.remove_client_colour(/datum/client_colour/monochrome) quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
+2 -2
View File
@@ -126,7 +126,7 @@
return examine(user) return examine(user)
//Start growing a human clone in the pod! //Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/traits) /obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/quirks)
if(panel_open) if(panel_open)
return FALSE return FALSE
if(mess || attempting) if(mess || attempting)
@@ -203,7 +203,7 @@
if(H) if(H)
H.faction |= factions H.faction |= factions
for(var/V in traits) for(var/V in quirks)
new V(H) new V(H)
H.set_cloned_appearance() H.set_cloned_appearance()
+6 -6
View File
@@ -71,7 +71,7 @@
if(pod.occupant) if(pod.occupant)
continue //how though? continue //how though?
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["traits"])) if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"]))
temp = "[R.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>" temp = "[R.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
records -= R records -= R
@@ -400,7 +400,7 @@
else if(pod.occupant) else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>" temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["traits"])) else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"]))
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>" temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
records.Remove(C) records.Remove(C)
@@ -473,10 +473,10 @@
R.fields["blood_type"] = dna.blood_type R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features R.fields["features"] = dna.features
R.fields["factions"] = mob_occupant.faction R.fields["factions"] = mob_occupant.faction
R.fields["traits"] = list() R.fields["quirks"] = list()
for(var/V in mob_occupant.roundstart_traits) for(var/V in mob_occupant.roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
R.fields["traits"] += T.type R.fields["quirks"] += T.type
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "[REF(mob_occupant.mind)]" R.fields["mind"] = "[REF(mob_occupant.mind)]"
+1 -1
View File
@@ -174,7 +174,7 @@ GAS ANALYZER
trauma_desc += B.scan_desc trauma_desc += B.scan_desc
trauma_text += trauma_desc trauma_text += trauma_desc
to_chat(user, "\t<span class='alert'>Cerebral traumas detected: subjects appears to be suffering from [english_list(trauma_text)].</span>") to_chat(user, "\t<span class='alert'>Cerebral traumas detected: subjects appears to be suffering from [english_list(trauma_text)].</span>")
if(C.roundstart_traits.len) if(C.roundstart_quirks.len)
to_chat(user, "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>") to_chat(user, "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>")
if(advanced) if(advanced)
to_chat(user, "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>") to_chat(user, "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>")
+82 -82
View File
@@ -83,12 +83,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Mob preview //Mob preview
var/icon/preview_icon = null var/icon/preview_icon = null
//Trait list //Quirk list
var/list/positive_traits = list() var/list/positive_quirks = list()
var/list/negative_traits = list() var/list/negative_quirks = list()
var/list/neutral_traits = list() var/list/neutral_quirks = list()
var/list/all_traits = list() var/list/all_quirks = list()
var/list/character_traits = list() var/list/character_quirks = list()
//Jobs, uses bitflags //Jobs, uses bitflags
var/job_civilian_high = 0 var/job_civilian_high = 0
@@ -195,9 +195,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<center><h2>Occupation Choices</h2>" dat += "<center><h2>Occupation Choices</h2>"
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>" dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
if(CONFIG_GET(flag/roundstart_traits)) if(CONFIG_GET(flag/roundstart_traits))
dat += "<center><h2>Trait Setup</h2>" dat += "<center><h2>Quirk Setup</h2>"
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Traits</a><br></center>" dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Quirks</a><br></center>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>" dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
dat += "<h2>Identity</h2>" dat += "<h2>Identity</h2>"
dat += "<table width='100%'><tr><td width='75%' valign='top'>" dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(jobban_isbanned(user, "appearance")) if(jobban_isbanned(user, "appearance"))
@@ -859,72 +859,72 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return job_engsec_low return job_engsec_low
return 0 return 0
/datum/preferences/proc/SetTraits(mob/user) /datum/preferences/proc/SetQuirks(mob/user)
if(!SStraits) if(!SSquirks)
to_chat(user, "<span class='danger'>The trait subsystem is still initializing! Try again in a minute.</span>") to_chat(user, "<span class='danger'>The quirk subsystem is still initializing! Try again in a minute.</span>")
return return
var/list/dat = list() var/list/dat = list()
if(!SStraits.traits.len) if(!SSquirks.quirks.len)
dat += "The trait subsystem hasn't finished initializing, please hold..." dat += "The quirk subsystem hasn't finished initializing, please hold..."
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>" dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>"
else else
dat += "<center><b>Choose trait setup</b></center><br>" dat += "<center><b>Choose quirk setup</b></center><br>"
dat += "<div align='center'>Left-click to add or remove traits. You need one negative trait for every positive trait.<br>\ dat += "<div align='center'>Left-click to add or remove quirks. You need negative quirks to have positive ones.<br>\
Traits are applied at roundstart and cannot normally be removed.</div>" Quirks are applied at roundstart and cannot normally be removed.</div>"
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center>" dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center>"
dat += "<hr>" dat += "<hr>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>" dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
dat += "<center>[all_traits.len] / [MAX_TRAITS] max traits<br>\ dat += "<center>[all_quirks.len] / [MAX_QUIRKS] max quirks<br>\
<b>Trait balance remaining:</b> [GetTraitBalance()]</center><br>" <b>Quirk balance remaining:</b> [GetQuirkBalance()]</center><br>"
for(var/V in SStraits.traits) for(var/V in SSquirks.quirks)
var/datum/trait/T = SStraits.traits[V] var/datum/quirk/T = SSquirks.quirks[V]
var/trait_name = initial(T.name) var/quirk_name = initial(T.name)
var/has_trait var/has_quirk
var/trait_cost = initial(T.value) * -1 var/quirk_cost = initial(T.value) * -1
var/lock_reason = "This trait is unavailable." var/lock_reason = "This trait is unavailable."
var/trait_conflict = FALSE var/quirk_conflict = FALSE
for(var/_V in all_traits) for(var/_V in all_quirks)
if(_V == trait_name) if(_V == quirk_name)
has_trait = TRUE has_quirk = TRUE
if(initial(T.mood_trait) && CONFIG_GET(flag/disable_human_mood)) if(initial(T.mood_quirk) && CONFIG_GET(flag/disable_human_mood))
lock_reason = "Mood is disabled." lock_reason = "Mood is disabled."
trait_conflict = TRUE quirk_conflict = TRUE
if(has_trait) if(has_quirk)
if(trait_conflict) if(quirk_conflict)
all_traits -= trait_name all_quirks -= quirk_name
has_trait = FALSE has_quirk = FALSE
else else
trait_cost *= -1 //invert it back, since we'd be regaining this amount quirk_cost *= -1 //invert it back, since we'd be regaining this amount
if(trait_cost > 0) if(quirk_cost > 0)
trait_cost = "+[trait_cost]" quirk_cost = "+[quirk_cost]"
var/font_color = "#AAAAFF" var/font_color = "#AAAAFF"
if(initial(T.value) != 0) if(initial(T.value) != 0)
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA" font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
if(trait_conflict) if(quirk_conflict)
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \ dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>" <font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
else else
if(has_trait) if(has_quirk)
dat += "<b><font color='[font_color]'>[trait_name]</font></b> - [initial(T.desc)] \ dat += "<b><font color='[font_color]'>[quirk_name]</font></b> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>" <a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
else else
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \ dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>" <a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>" dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>"
user << browse(null, "window=preferences") user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Trait Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Quirk Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
popup.set_window_options("can_close=0") popup.set_window_options("can_close=0")
popup.set_content(dat.Join()) popup.set_content(dat.Join())
popup.open(0) popup.open(0)
return return
/datum/preferences/proc/GetTraitBalance() /datum/preferences/proc/GetQuirkBalance()
var/bal = 0 var/bal = 0
for(var/V in all_traits) for(var/V in all_quirks)
var/datum/trait/T = SStraits.traits[V] var/datum/quirk/T = SSquirks.quirks[V]
bal -= initial(T.value) bal -= initial(T.value)
return bal return bal
@@ -981,55 +981,55 @@ GLOBAL_LIST_EMPTY(preferences_datums)
user << browse(null, "window=mob_occupation") user << browse(null, "window=mob_occupation")
ShowChoices(user) ShowChoices(user)
if("update") if("update")
var/trait = href_list["trait"] var/quirk = href_list["trait"]
if(!SStraits.traits[trait]) if(!SSquirks.quirks[quirk])
return return
var/value = SStraits.trait_points[trait] var/value = SSquirks.quirk_points[quirk]
if(value == 0) if(value == 0)
if(trait in neutral_traits) if(quirk in neutral_quirks)
neutral_traits -= trait neutral_quirks -= quirk
all_traits -= trait all_quirks -= quirk
else else
if(all_traits.len >= MAX_TRAITS) if(all_quirks.len >= MAX_QUIRKS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>") to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
return return
neutral_traits += trait neutral_quirks += quirk
all_traits += trait all_quirks += quirk
else else
var/balance = GetTraitBalance() var/balance = GetQuirkBalance()
if(trait in positive_traits) if(quirk in positive_quirks)
positive_traits -= trait positive_quirks -= quirk
all_traits -= trait all_quirks -= quirk
else if(trait in negative_traits) else if(quirk in negative_quirks)
if(balance + value < 0) if(balance + value < 0)
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>") to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
return return
negative_traits -= trait negative_quirks -= quirk
all_traits -= trait all_quirks -= quirk
else if(value > 0) else if(value > 0)
if(all_traits.len >= MAX_TRAITS) if(all_quirks.len >= MAX_QUIRKS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>") to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
return return
if(balance - value < 0) if(balance - value < 0)
to_chat(user, "<span class='warning'>You don't have enough balance to gain this trait!</span>") to_chat(user, "<span class='warning'>You don't have enough balance to gain this quirk!</span>")
return return
positive_traits += trait positive_quirks += quirk
all_traits += trait all_quirks += quirk
else else
if(all_traits.len >= MAX_TRAITS) if(all_quirks.len >= MAX_QUIRKS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>") to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
return return
negative_traits += trait negative_quirks += quirk
all_traits += trait all_quirks += quirk
SetTraits(user) SetQuirks(user)
if("reset") if("reset")
all_traits = list() all_quirks = list()
positive_traits = list() positive_quirks = list()
negative_traits = list() negative_quirks = list()
neutral_traits = list() neutral_quirks = list()
SetTraits(user) SetQuirks(user)
else else
SetTraits(user) SetQuirks(user)
return TRUE return TRUE
switch(href_list["task"]) switch(href_list["task"])
+14 -14
View File
@@ -313,11 +313,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["job_engsec_med"] >> job_engsec_med S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low S["job_engsec_low"] >> job_engsec_low
//Traits //Quirks
S["all_traits"] >> all_traits S["all_quirks"] >> all_quirks
S["positive_traits"] >> positive_traits S["positive_quirks"] >> positive_quirks
S["negative_traits"] >> negative_traits S["negative_quirks"] >> negative_quirks
S["neutral_traits"] >> neutral_traits S["neutral_quirks"] >> neutral_quirks
//Citadel code //Citadel code
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"] S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
@@ -424,10 +424,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med)) job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low)) job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
all_traits = SANITIZE_LIST(all_traits) all_quirks = SANITIZE_LIST(all_quirks)
positive_traits = SANITIZE_LIST(positive_traits) positive_quirks = SANITIZE_LIST(positive_quirks)
negative_traits = SANITIZE_LIST(negative_traits) negative_quirks = SANITIZE_LIST(negative_quirks)
neutral_traits = SANITIZE_LIST(neutral_traits) neutral_quirks = SANITIZE_LIST(neutral_quirks)
cit_character_pref_load(S) cit_character_pref_load(S)
@@ -494,11 +494,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["job_engsec_med"] , job_engsec_med) WRITE_FILE(S["job_engsec_med"] , job_engsec_med)
WRITE_FILE(S["job_engsec_low"] , job_engsec_low) WRITE_FILE(S["job_engsec_low"] , job_engsec_low)
//Traits //Quirks
WRITE_FILE(S["all_traits"] , all_traits) WRITE_FILE(S["all_quirks"] , all_quirks)
WRITE_FILE(S["positive_traits"] , positive_traits) WRITE_FILE(S["positive_quirks"] , positive_quirks)
WRITE_FILE(S["negative_traits"] , negative_traits) WRITE_FILE(S["negative_quirks"] , negative_quirks)
WRITE_FILE(S["neutral_traits"] , neutral_traits) WRITE_FILE(S["neutral_quirks"] , neutral_quirks)
cit_character_pref_save(S) cit_character_pref_save(S)
+3 -3
View File
@@ -22,7 +22,7 @@
var/blood_type = null var/blood_type = null
var/list/features = null var/list/features = null
var/factions = null var/factions = null
var/list/traits = null var/list/quirks = null
var/contains_sample = 0 var/contains_sample = 0
/obj/item/seeds/replicapod/Initialize() /obj/item/seeds/replicapod/Initialize()
@@ -42,7 +42,7 @@
blood_type = B.data["blood_type"] blood_type = B.data["blood_type"]
features = B.data["features"] features = B.data["features"]
factions = B.data["factions"] factions = B.data["factions"]
factions = B.data["traits"] factions = B.data["quirks"]
contains_sample = TRUE contains_sample = TRUE
visible_message("<span class='notice'>The [src] is injected with a fresh blood sample.</span>") visible_message("<span class='notice'>The [src] is injected with a fresh blood sample.</span>")
else else
@@ -114,7 +114,7 @@
podman.faction |= factions podman.faction |= factions
if(!features["mcolor"]) if(!features["mcolor"])
features["mcolor"] = "#59CE00" features["mcolor"] = "#59CE00"
for(var/V in traits) for(var/V in quirks)
new V(podman) new V(podman)
podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance() podman.set_cloned_appearance()
@@ -400,7 +400,7 @@
SSticker.mode.make_antag_chance(humanc) SSticker.mode.make_antag_chance(humanc)
if(humanc && CONFIG_GET(flag/roundstart_traits)) if(humanc && CONFIG_GET(flag/roundstart_traits))
SStraits.AssignTraits(humanc, humanc.client, TRUE) SSquirks.AssignQuirks(humanc, humanc.client, TRUE)
log_manifest(character.mind.key,character.mind,character,latejoin = TRUE) log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
+4 -4
View File
@@ -193,10 +193,10 @@
blood_data["real_name"] = real_name blood_data["real_name"] = real_name
blood_data["features"] = dna.features blood_data["features"] = dna.features
blood_data["factions"] = faction blood_data["factions"] = faction
blood_data["traits"] = list() blood_data["quirks"] = list()
for(var/V in roundstart_traits) for(var/V in roundstart_quirks)
var/datum/trait/T = V var/datum/quirk/T = V
blood_data["traits"] += T.type blood_data["quirks"] += T.type
return blood_data return blood_data
//get the id of the substance this mob use as blood. //get the id of the substance this mob use as blood.
@@ -733,8 +733,8 @@
if(0 to NUTRITION_LEVEL_STARVING) if(0 to NUTRITION_LEVEL_STARVING)
to_chat(src, "<span class='danger'>You're starving!</span>") to_chat(src, "<span class='danger'>You're starving!</span>")
if(roundstart_traits.len) if(roundstart_quirks.len)
to_chat(src, "<span class='notice'>You have these traits: [get_trait_string()].</span>") to_chat(src, "<span class='notice'>You have these quirks: [get_trait_string()].</span>")
else else
if(wear_suit) if(wear_suit)
wear_suit.add_fingerprint(M) wear_suit.add_fingerprint(M)
+1 -1
View File
@@ -34,7 +34,7 @@
var/list/status_traits = list() var/list/status_traits = list()
var/list/roundstart_traits = list() var/list/roundstart_quirks = list()
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them. var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
+8 -8
View File
@@ -146,12 +146,12 @@
else else
status_traits[trait] |= list(source) status_traits[trait] |= list(source)
/mob/living/proc/add_trait_datum(trait, spawn_effects) //separate proc due to the way these ones are handled /mob/living/proc/add_quirk(quirk, spawn_effects) //separate proc due to the way these ones are handled
if(has_trait(trait)) if(has_trait(quirk))
return return
if(!SStraits || !SStraits.traits[trait]) if(!SSquirks || !SSquirks.quirks[quirk])
return return
var/datum/trait/T = SStraits.traits[trait] var/datum/quirk/T = SSquirks.quirks[quirk]
new T (src, spawn_effects) new T (src, spawn_effects)
return TRUE return TRUE
@@ -180,8 +180,8 @@
if(!LAZYLEN(status_traits[trait])) if(!LAZYLEN(status_traits[trait]))
status_traits -= trait status_traits -= trait
/mob/living/proc/remove_trait_datum(trait) /mob/living/proc/remove_quirk(quirk)
var/datum/trait/T = roundstart_traits[trait] var/datum/quirk/T = roundstart_quirks[quirk]
if(T) if(T)
qdel(T) qdel(T)
return TRUE return TRUE
@@ -201,8 +201,8 @@
else if(LAZYLEN(status_traits[trait])) else if(LAZYLEN(status_traits[trait]))
return TRUE return TRUE
/mob/living/proc/has_trait_datum(trait) /mob/living/proc/has_quirk(quirk)
return roundstart_traits[trait] return roundstart_quirks[quirk]
/mob/living/proc/remove_all_traits() /mob/living/proc/remove_all_traits()
status_traits = list() status_traits = list()
+2 -1
View File
@@ -536,7 +536,8 @@ ALLOW_MISCREANTS
## Determines if players are allowed to print integrated circuits, uncomment to allow. ## Determines if players are allowed to print integrated circuits, uncomment to allow.
#IC_PRINTING #IC_PRINTING
## Uncomment to allow roundstart trait selection in the character setup menu. ## Uncomment to allow roundstart quirk selection in the character setup menu.
## This used to be named traits, hence the config name, but it handles quirks, not the other kind of trait!
ROUNDSTART_TRAITS ROUNDSTART_TRAITS
## Uncomment to disable human moods. ## Uncomment to disable human moods.
@@ -1,24 +1,24 @@
// Citadel-specific Neutral Traits // Citadel-specific Neutral Traits
/datum/trait/libido /datum/quirk/libido
name = "Nymphomania" name = "Nymphomania"
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual." desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
value = 0 value = 0
gain_text = "<span class='notice'>You are feeling extra wild.</span>" gain_text = "<span class='notice'>You are feeling extra wild.</span>"
lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>" lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>"
/datum/trait/libido/add() /datum/quirk/libido/add()
var/mob/living/M = trait_holder var/mob/living/M = quirk_holder
M.min_arousal = 16 M.min_arousal = 16
M.arousal_rate = 3 M.arousal_rate = 3
/datum/trait/libido/remove() /datum/quirk/libido/remove()
var/mob/living/M = trait_holder var/mob/living/M = quirk_holder
M.min_arousal = initial(M.min_arousal) M.min_arousal = initial(M.min_arousal)
M.arousal_rate = initial(M.arousal_rate) M.arousal_rate = initial(M.arousal_rate)
/datum/trait/libido/on_process() /datum/quirk/libido/on_process()
var/mob/living/M = trait_holder var/mob/living/M = quirk_holder
if(M.canbearoused == FALSE) if(M.canbearoused == FALSE)
to_chat(trait_holder, "<span class='notice'>Having high libido is useless when you can't feel arousal at all!</span>") to_chat(quirk_holder, "<span class='notice'>Having high libido is useless when you can't feel arousal at all!</span>")
qdel(src) qdel(src)
+2 -2
View File
@@ -261,7 +261,7 @@
#include "code\controllers\subsystem\processing\obj.dm" #include "code\controllers\subsystem\processing\obj.dm"
#include "code\controllers\subsystem\processing\processing.dm" #include "code\controllers\subsystem\processing\processing.dm"
#include "code\controllers\subsystem\processing\projectiles.dm" #include "code\controllers\subsystem\processing\projectiles.dm"
#include "code\controllers\subsystem\processing\traits.dm" #include "code\controllers\subsystem\processing\quirks.dm"
#include "code\controllers\subsystem\processing\wet_floors.dm" #include "code\controllers\subsystem\processing\wet_floors.dm"
#include "code\datums\action.dm" #include "code\datums\action.dm"
#include "code\datums\ai_laws.dm" #include "code\datums\ai_laws.dm"
@@ -445,7 +445,7 @@
#include "code\datums\status_effects\gas.dm" #include "code\datums\status_effects\gas.dm"
#include "code\datums\status_effects\neutral.dm" #include "code\datums\status_effects\neutral.dm"
#include "code\datums\status_effects\status_effect.dm" #include "code\datums\status_effects\status_effect.dm"
#include "code\datums\traits\_trait.dm" #include "code\datums\traits\_quirk.dm"
#include "code\datums\traits\good.dm" #include "code\datums\traits\good.dm"
#include "code\datums\traits\negative.dm" #include "code\datums\traits\negative.dm"
#include "code\datums\traits\neutral.dm" #include "code\datums\traits\neutral.dm"