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:
@@ -258,7 +258,7 @@
|
||||
|
||||
// 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
|
||||
#define AI_CAMERA_LUMINOSITY 5
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#define INIT_ORDER_RESEARCH 14
|
||||
#define INIT_ORDER_EVENTS 13
|
||||
#define INIT_ORDER_JOBS 12
|
||||
#define INIT_ORDER_TRAITS 11
|
||||
#define INIT_ORDER_QUIRKS 11
|
||||
#define INIT_ORDER_TICKER 10
|
||||
#define INIT_ORDER_MAPPING 9
|
||||
#define INIT_ORDER_NETWORKS 8
|
||||
|
||||
34
code/controllers/subsystem/processing/quirks.dm
Normal file
34
code/controllers/subsystem/processing/quirks.dm
Normal file
@@ -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
|
||||
@@ -391,7 +391,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(player.mind.assigned_role != player.mind.special_role)
|
||||
SSjob.EquipRank(N, player.mind.assigned_role, 0)
|
||||
if(CONFIG_GET(flag/roundstart_traits))
|
||||
SStraits.AssignTraits(player, N.client, TRUE)
|
||||
SSquirks.AssignQuirks(player, N.client, TRUE)
|
||||
CHECK_TICK
|
||||
if(captainless)
|
||||
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
|
||||
//these are NOT "mob traits" like GOTTAGOFAST, but exist as a medium to apply them and other different effects
|
||||
/datum/trait
|
||||
var/name = "Test Trait"
|
||||
var/desc = "This is a test trait."
|
||||
//every quirk in this folder should be coded around being applied on spawn
|
||||
//these are NOT "mob quirks" like GOTTAGOFAST, but exist as a medium to apply them and other different effects
|
||||
/datum/quirk
|
||||
var/name = "Test Quirk"
|
||||
var/desc = "This is a test quirk."
|
||||
var/value = 0
|
||||
var/human_only = TRUE
|
||||
var/gain_text
|
||||
var/lose_text
|
||||
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/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)
|
||||
trait_holder = trait_mob
|
||||
SStraits.trait_objects += src
|
||||
to_chat(trait_holder, gain_text)
|
||||
trait_holder.roundstart_traits += src
|
||||
quirk_holder = quirk_mob
|
||||
SSquirks.quirk_objects += src
|
||||
to_chat(quirk_holder, gain_text)
|
||||
quirk_holder.roundstart_quirks += src
|
||||
if(mob_trait)
|
||||
trait_holder.add_trait(mob_trait, ROUNDSTART_TRAIT)
|
||||
START_PROCESSING(SStraits, src)
|
||||
quirk_holder.add_trait(mob_trait, ROUNDSTART_TRAIT)
|
||||
START_PROCESSING(SSquirks, src)
|
||||
add()
|
||||
if(spawn_effects)
|
||||
on_spawn()
|
||||
addtimer(CALLBACK(src, .proc/post_add), 30)
|
||||
|
||||
/datum/trait/Destroy()
|
||||
STOP_PROCESSING(SStraits, src)
|
||||
/datum/quirk/Destroy()
|
||||
STOP_PROCESSING(SSquirks, src)
|
||||
remove()
|
||||
if(trait_holder)
|
||||
to_chat(trait_holder, lose_text)
|
||||
trait_holder.roundstart_traits -= src
|
||||
if(quirk_holder)
|
||||
to_chat(quirk_holder, lose_text)
|
||||
quirk_holder.roundstart_quirks -= src
|
||||
if(mob_trait)
|
||||
trait_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE)
|
||||
SStraits.trait_objects -= src
|
||||
quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE)
|
||||
SSquirks.quirk_objects -= src
|
||||
return ..()
|
||||
|
||||
/datum/trait/proc/transfer_mob(mob/living/to_mob)
|
||||
trait_holder.roundstart_traits -= src
|
||||
to_mob.roundstart_traits += src
|
||||
/datum/quirk/proc/transfer_mob(mob/living/to_mob)
|
||||
quirk_holder.roundstart_quirks -= src
|
||||
to_mob.roundstart_quirks += src
|
||||
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)
|
||||
trait_holder = to_mob
|
||||
quirk_holder = to_mob
|
||||
on_transfer()
|
||||
|
||||
/datum/trait/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/trait/proc/remove() //special "on remove" effects
|
||||
/datum/trait/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/trait/proc/on_transfer() //code called when the trait is transferred to a new mob
|
||||
/datum/quirk/proc/add() //special "on add" effects
|
||||
/datum/quirk/proc/on_spawn() //these should only trigger when the character is being created for the first time, i.e. roundstart/latejoin
|
||||
/datum/quirk/proc/remove() //special "on remove" effects
|
||||
/datum/quirk/proc/on_process() //process() has some special checks, so this is the actual process
|
||||
/datum/quirk/proc/post_add() //for text, disclaimers etc. given after you spawn in with the trait
|
||||
/datum/quirk/proc/on_transfer() //code called when the trait is transferred to a new mob
|
||||
|
||||
/datum/trait/process()
|
||||
if(QDELETED(trait_holder))
|
||||
trait_holder = null
|
||||
/datum/quirk/process()
|
||||
if(QDELETED(quirk_holder))
|
||||
quirk_holder = null
|
||||
qdel(src)
|
||||
return
|
||||
if(trait_holder.stat == DEAD)
|
||||
if(quirk_holder.stat == DEAD)
|
||||
return
|
||||
on_process()
|
||||
|
||||
/mob/living/proc/get_trait_string(medical) //helper string. gets a string of all the traits the mob has
|
||||
var/list/dat = list()
|
||||
if(!medical)
|
||||
for(var/V in roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
for(var/V in roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
dat += T.name
|
||||
if(!dat.len)
|
||||
return "None"
|
||||
return dat.Join(", ")
|
||||
else
|
||||
for(var/V in roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
for(var/V in roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
dat += T.medical_record_text
|
||||
if(!dat.len)
|
||||
return "None"
|
||||
return dat.Join("<br>")
|
||||
|
||||
/mob/living/proc/cleanse_trait_datums() //removes all trait datums
|
||||
for(var/V in roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
for(var/V in roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
qdel(T)
|
||||
|
||||
/mob/living/proc/transfer_trait_datums(mob/living/to_mob)
|
||||
for(var/V in roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
for(var/V in roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
T.transfer_mob(to_mob)
|
||||
|
||||
/*
|
||||
@@ -96,7 +96,7 @@
|
||||
Commented version of Nearsighted to help you add your own traits
|
||||
Use this as a guideline
|
||||
|
||||
/datum/trait/nearsighted
|
||||
/datum/quirk/nearsighted
|
||||
name = "Nearsighted"
|
||||
///The trait's name
|
||||
|
||||
@@ -116,8 +116,8 @@ Use this as a guideline
|
||||
medical_record_text = "Subject has permanent nearsightedness."
|
||||
///These three are self-explanatory
|
||||
|
||||
/datum/trait/nearsighted/on_spawn()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/nearsighted/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
|
||||
H.put_in_hands(glasses)
|
||||
H.equip_to_slot(glasses, slot_glasses)
|
||||
@@ -1,7 +1,7 @@
|
||||
//predominantly positive traits
|
||||
//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"
|
||||
desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol."
|
||||
value = 1
|
||||
@@ -11,25 +11,25 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/apathetic
|
||||
/datum/quirk/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."
|
||||
value = 1
|
||||
mood_trait = TRUE
|
||||
mood_quirk = TRUE
|
||||
|
||||
/datum/trait/apathetic/add()
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder)
|
||||
/datum/quirk/apathetic/add()
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
|
||||
if(mood)
|
||||
mood.mood_modifier = 0.8
|
||||
|
||||
/datum/trait/apathetic/remove()
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder)
|
||||
/datum/quirk/apathetic/remove()
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
|
||||
if(mood)
|
||||
mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers.
|
||||
|
||||
|
||||
|
||||
/datum/trait/freerunning
|
||||
/datum/quirk/freerunning
|
||||
name = "Freerunning"
|
||||
desc = "You're great at quick moves! You can climb tables more quickly."
|
||||
value = 2
|
||||
@@ -39,16 +39,16 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/jolly
|
||||
/datum/quirk/jolly
|
||||
name = "Jolly"
|
||||
desc = "You sometimes just feel happy, for no reason at all."
|
||||
value = 1
|
||||
mob_trait = TRAIT_JOLLY
|
||||
mood_trait = TRUE
|
||||
mood_quirk = TRUE
|
||||
|
||||
|
||||
|
||||
/datum/trait/light_step
|
||||
/datum/quirk/light_step
|
||||
name = "Light Step"
|
||||
desc = "You walk with a gentle step, making stepping on sharp objects quieter and less painful."
|
||||
value = 1
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/night_vision
|
||||
/datum/quirk/night_vision
|
||||
name = "Night Vision"
|
||||
desc = "You can see slightly more clearly in full darkness than most people."
|
||||
value = 1
|
||||
@@ -66,8 +66,8 @@
|
||||
gain_text = "<span class='notice'>The shadows seem a little less dark.</span>"
|
||||
lose_text = "<span class='danger'>Everything seems a little darker.</span>"
|
||||
|
||||
/datum/trait/night_vision/on_spawn()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/night_vision/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/organ/eyes/eyes = H.getorgan(/obj/item/organ/eyes)
|
||||
if(!eyes || eyes.lighting_alpha)
|
||||
return
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/selfaware
|
||||
/datum/quirk/selfaware
|
||||
name = "Self-Aware"
|
||||
desc = "You know your body well, and can accurately assess the extent of your wounds."
|
||||
value = 2
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/skittish
|
||||
/datum/quirk/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."
|
||||
value = 2
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/spiritual
|
||||
/datum/quirk/spiritual
|
||||
name = "Spiritual"
|
||||
desc = "You're in tune with the gods, and your prayers may be more likely to be heard. Or not."
|
||||
value = 1
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/voracious
|
||||
/datum/quirk/voracious
|
||||
name = "Voracious"
|
||||
desc = "Nothing gets between you and your food. You eat twice as fast as everyone else!"
|
||||
value = 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//predominantly negative traits
|
||||
|
||||
/datum/trait/blooddeficiency
|
||||
/datum/quirk/blooddeficiency
|
||||
name = "Acute Blood Deficiency"
|
||||
desc = "Your body can't produce enough blood to sustain itself."
|
||||
value = -2
|
||||
@@ -8,12 +8,12 @@
|
||||
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."
|
||||
|
||||
/datum/trait/blooddeficiency/on_process()
|
||||
trait_holder.blood_volume -= 0.275
|
||||
/datum/quirk/blooddeficiency/on_process()
|
||||
quirk_holder.blood_volume -= 0.275
|
||||
|
||||
|
||||
|
||||
/datum/trait/depression
|
||||
/datum/quirk/depression
|
||||
name = "Depression"
|
||||
desc = "You sometimes just hate life."
|
||||
mob_trait = TRAIT_DEPRESSION
|
||||
@@ -21,22 +21,22 @@
|
||||
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!
|
||||
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"
|
||||
desc = "You are the current owner of an heirloom. passed down for generations. You have to keep it safe!"
|
||||
value = -1
|
||||
mood_trait = TRUE
|
||||
mood_quirk = TRUE
|
||||
var/obj/item/heirloom
|
||||
var/where_text
|
||||
|
||||
/datum/trait/family_heirloom/on_spawn()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/family_heirloom/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/heirloom_type
|
||||
switch(trait_holder.mind.assigned_role)
|
||||
switch(quirk_holder.mind.assigned_role)
|
||||
if("Clown")
|
||||
heirloom_type = /obj/item/bikehorn/golden
|
||||
if("Mime")
|
||||
@@ -56,7 +56,7 @@
|
||||
/obj/item/toy/cards/deck,
|
||||
/obj/item/lighter,
|
||||
/obj/item/dice/d20)
|
||||
heirloom = new heirloom_type(get_turf(trait_holder))
|
||||
heirloom = new heirloom_type(get_turf(quirk_holder))
|
||||
var/list/slots = list(
|
||||
"in your backpack" = slot_in_backpack,
|
||||
"in your left pocket" = slot_l_store,
|
||||
@@ -69,22 +69,22 @@
|
||||
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>"
|
||||
|
||||
/datum/trait/family_heirloom/post_add()
|
||||
to_chat(trait_holder, where_text)
|
||||
var/list/family_name = splittext(trait_holder.real_name, " ")
|
||||
/datum/quirk/family_heirloom/post_add()
|
||||
to_chat(quirk_holder, where_text)
|
||||
var/list/family_name = splittext(quirk_holder.real_name, " ")
|
||||
heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]"
|
||||
|
||||
/datum/trait/family_heirloom/on_process()
|
||||
if(heirloom in trait_holder.GetAllContents())
|
||||
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
|
||||
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
|
||||
/datum/quirk/family_heirloom/on_process()
|
||||
if(heirloom in quirk_holder.GetAllContents())
|
||||
quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
|
||||
quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
|
||||
else
|
||||
trait_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_CLEAR_MOOD_EVENT, "family_heirloom")
|
||||
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"
|
||||
desc = "You sleep like a rock! Whenever you're put to sleep, you sleep for a little bit longer."
|
||||
value = -1
|
||||
@@ -93,7 +93,7 @@
|
||||
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."
|
||||
|
||||
/datum/trait/brainproblems
|
||||
/datum/quirk/brainproblems
|
||||
name = "Brain Tumor"
|
||||
desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!"
|
||||
value = -3
|
||||
@@ -101,12 +101,12 @@
|
||||
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."
|
||||
|
||||
/datum/trait/brainproblems/on_process()
|
||||
trait_holder.adjustBrainLoss(0.2)
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustBrainLoss(0.2)
|
||||
|
||||
|
||||
|
||||
/datum/trait/nearsighted //t. errorage
|
||||
/datum/quirk/nearsighted //t. errorage
|
||||
name = "Nearsighted"
|
||||
desc = "You are nearsighted without prescription glasses, but spawn with a pair."
|
||||
value = -1
|
||||
@@ -114,11 +114,11 @@
|
||||
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."
|
||||
|
||||
/datum/trait/nearsighted/add()
|
||||
trait_holder.become_nearsighted(ROUNDSTART_TRAIT)
|
||||
/datum/quirk/nearsighted/add()
|
||||
quirk_holder.become_nearsighted(ROUNDSTART_TRAIT)
|
||||
|
||||
/datum/trait/nearsighted/on_spawn()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/nearsighted/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
|
||||
H.put_in_hands(glasses)
|
||||
H.equip_to_slot(glasses, slot_glasses)
|
||||
@@ -126,28 +126,28 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/nyctophobia
|
||||
/datum/quirk/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."
|
||||
value = -1
|
||||
|
||||
/datum/trait/nyctophobia/on_process()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/nyctophobia/on_process()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
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
|
||||
var/turf/T = get_turf(trait_holder)
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
if(lums <= 0.2)
|
||||
if(trait_holder.m_intent == MOVE_INTENT_RUN)
|
||||
to_chat(trait_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
|
||||
trait_holder.toggle_move_intent()
|
||||
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
|
||||
to_chat(quirk_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
|
||||
quirk_holder.toggle_move_intent()
|
||||
quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
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"
|
||||
desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
|
||||
value = -2
|
||||
@@ -156,14 +156,14 @@
|
||||
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."
|
||||
|
||||
/datum/trait/nonviolent/on_process()
|
||||
if(trait_holder.mind && LAZYLEN(trait_holder.mind.antag_datums))
|
||||
to_chat(trait_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
|
||||
/datum/quirk/nonviolent/on_process()
|
||||
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
/datum/trait/poor_aim
|
||||
/datum/quirk/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."
|
||||
value = -1
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/prosopagnosia
|
||||
/datum/quirk/prosopagnosia
|
||||
name = "Prosopagnosia"
|
||||
desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
|
||||
value = -1
|
||||
@@ -181,41 +181,41 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/prosthetic_limb
|
||||
/datum/quirk/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!"
|
||||
value = -1
|
||||
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/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/prosthetic
|
||||
switch(limb_slot)
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
prosthetic.replace_limb(H)
|
||||
qdel(old_part)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/trait/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, \
|
||||
/datum/quirk/prosthetic_limb/post_add()
|
||||
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>")
|
||||
|
||||
|
||||
|
||||
/datum/trait/insanity
|
||||
/datum/quirk/insanity
|
||||
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>"
|
||||
value = -2
|
||||
@@ -224,32 +224,32 @@
|
||||
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."
|
||||
|
||||
/datum/trait/insanity/on_process()
|
||||
if(trait_holder.reagents.has_reagent("mindbreaker"))
|
||||
trait_holder.hallucination = 0
|
||||
/datum/quirk/insanity/on_process()
|
||||
if(quirk_holder.reagents.has_reagent("mindbreaker"))
|
||||
quirk_holder.hallucination = 0
|
||||
return
|
||||
if(prob(2)) //we'll all be mad soon enough
|
||||
madness()
|
||||
|
||||
/datum/trait/insanity/proc/madness(mad_fools)
|
||||
/datum/quirk/insanity/proc/madness(mad_fools)
|
||||
set waitfor = FALSE
|
||||
if(!mad_fools)
|
||||
mad_fools = prob(20)
|
||||
if(mad_fools)
|
||||
var/hallucination_type = pick(subtypesof(/datum/hallucination/rds))
|
||||
new hallucination_type (trait_holder, FALSE)
|
||||
new hallucination_type (quirk_holder, FALSE)
|
||||
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
|
||||
if(!trait_holder.mind || trait_holder.mind.special_role)
|
||||
/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(!quirk_holder.mind || quirk_holder.mind.special_role)
|
||||
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>")
|
||||
|
||||
|
||||
|
||||
/datum/trait/social_anxiety
|
||||
/datum/quirk/social_anxiety
|
||||
name = "Social Anxiety"
|
||||
desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
|
||||
value = -1
|
||||
@@ -258,12 +258,12 @@
|
||||
medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
|
||||
var/dumb_thing = TRUE
|
||||
|
||||
/datum/trait/social_anxiety/on_process()
|
||||
/datum/quirk/social_anxiety/on_process()
|
||||
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)
|
||||
nearby_people++
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(prob(2 + nearby_people))
|
||||
H.stuttering = max(3, H.stuttering)
|
||||
else if(prob(min(3, nearby_people)) && !H.silent)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//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.
|
||||
|
||||
/datum/trait/no_taste
|
||||
/datum/quirk/no_taste
|
||||
name = "Ageusia"
|
||||
desc = "You can't taste anything! Toxic food will still poison you."
|
||||
value = 0
|
||||
@@ -12,75 +12,75 @@
|
||||
|
||||
|
||||
|
||||
/datum/trait/pineapple_liker
|
||||
/datum/quirk/pineapple_liker
|
||||
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!"
|
||||
value = 0
|
||||
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>"
|
||||
|
||||
/datum/trait/pineapple_liker/add()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/pineapple_liker/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
species.liked_food |= PINEAPPLE
|
||||
|
||||
/datum/trait/pineapple_liker/remove()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/pineapple_liker/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
species.liked_food &= ~PINEAPPLE
|
||||
|
||||
/datum/trait/pineapple_hater
|
||||
/datum/quirk/pineapple_hater
|
||||
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!?"
|
||||
value = 0
|
||||
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>"
|
||||
|
||||
/datum/trait/pineapple_hater/add()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/pineapple_hater/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
species.disliked_food |= PINEAPPLE
|
||||
|
||||
/datum/trait/pineapple_hater/remove()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/pineapple_hater/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
species.disliked_food &= ~PINEAPPLE
|
||||
|
||||
/datum/trait/deviant_tastes
|
||||
/datum/quirk/deviant_tastes
|
||||
name = "Deviant Tastes"
|
||||
desc = "You dislike food that most people enjoy, and find delicious what they don't."
|
||||
value = 0
|
||||
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>"
|
||||
|
||||
/datum/trait/deviant_tastes/add()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/deviant_tastes/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
var/liked = species.liked_food
|
||||
species.liked_food = species.disliked_food
|
||||
species.disliked_food = liked
|
||||
|
||||
/datum/trait/deviant_tastes/remove()
|
||||
var/mob/living/carbon/human/H = trait_holder
|
||||
/datum/quirk/deviant_tastes/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/datum/species/species = H.dna.species
|
||||
species.liked_food = initial(species.liked_food)
|
||||
species.disliked_food = initial(species.disliked_food)
|
||||
|
||||
|
||||
|
||||
/datum/trait/monochromatic
|
||||
/datum/quirk/monochromatic
|
||||
name = "Monochromacy"
|
||||
desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
|
||||
value = 0
|
||||
medical_record_text = "Patient is afflicted with almost complete color blindness."
|
||||
|
||||
/datum/trait/monochromatic/add()
|
||||
trait_holder.add_client_colour(/datum/client_colour/monochrome)
|
||||
/datum/quirk/monochromatic/add()
|
||||
quirk_holder.add_client_colour(/datum/client_colour/monochrome)
|
||||
|
||||
/datum/trait/monochromatic/post_add()
|
||||
if(trait_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>")
|
||||
trait_holder.playsound_local(trait_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
|
||||
/datum/quirk/monochromatic/post_add()
|
||||
if(quirk_holder.mind.assigned_role == "Detective")
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Mmm. Nothing's ever clear on this station. It's all shades of gray...</span>")
|
||||
quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
|
||||
|
||||
/datum/trait/monochromatic/remove()
|
||||
trait_holder.remove_client_colour(/datum/client_colour/monochrome)
|
||||
/datum/quirk/monochromatic/remove()
|
||||
quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
return examine(user)
|
||||
|
||||
//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)
|
||||
return FALSE
|
||||
if(mess || attempting)
|
||||
@@ -203,7 +203,7 @@
|
||||
if(H)
|
||||
H.faction |= factions
|
||||
|
||||
for(var/V in traits)
|
||||
for(var/V in quirks)
|
||||
new V(H)
|
||||
|
||||
H.set_cloned_appearance()
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if(pod.occupant)
|
||||
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>"
|
||||
records -= R
|
||||
|
||||
@@ -400,7 +400,7 @@
|
||||
else if(pod.occupant)
|
||||
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
|
||||
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>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
records.Remove(C)
|
||||
@@ -473,10 +473,10 @@
|
||||
R.fields["blood_type"] = dna.blood_type
|
||||
R.fields["features"] = dna.features
|
||||
R.fields["factions"] = mob_occupant.faction
|
||||
R.fields["traits"] = list()
|
||||
for(var/V in mob_occupant.roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
R.fields["traits"] += T.type
|
||||
R.fields["quirks"] = list()
|
||||
for(var/V in mob_occupant.roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
R.fields["quirks"] += T.type
|
||||
|
||||
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
|
||||
R.fields["mind"] = "[REF(mob_occupant.mind)]"
|
||||
|
||||
@@ -174,7 +174,7 @@ GAS ANALYZER
|
||||
trauma_desc += B.scan_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>")
|
||||
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>")
|
||||
if(advanced)
|
||||
to_chat(user, "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>")
|
||||
|
||||
@@ -83,12 +83,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
//Mob preview
|
||||
var/icon/preview_icon = null
|
||||
|
||||
//Trait list
|
||||
var/list/positive_traits = list()
|
||||
var/list/negative_traits = list()
|
||||
var/list/neutral_traits = list()
|
||||
var/list/all_traits = list()
|
||||
var/list/character_traits = list()
|
||||
//Quirk list
|
||||
var/list/positive_quirks = list()
|
||||
var/list/negative_quirks = list()
|
||||
var/list/neutral_quirks = list()
|
||||
var/list/all_quirks = list()
|
||||
var/list/character_quirks = list()
|
||||
|
||||
//Jobs, uses bitflags
|
||||
var/job_civilian_high = 0
|
||||
@@ -195,9 +195,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<center><h2>Occupation Choices</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
|
||||
if(CONFIG_GET(flag/roundstart_traits))
|
||||
dat += "<center><h2>Trait Setup</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Traits</a><br></center>"
|
||||
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
|
||||
dat += "<center><h2>Quirk Setup</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Quirks</a><br></center>"
|
||||
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
|
||||
dat += "<h2>Identity</h2>"
|
||||
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
|
||||
if(jobban_isbanned(user, "appearance"))
|
||||
@@ -859,72 +859,72 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
return job_engsec_low
|
||||
return 0
|
||||
|
||||
/datum/preferences/proc/SetTraits(mob/user)
|
||||
if(!SStraits)
|
||||
to_chat(user, "<span class='danger'>The trait subsystem is still initializing! Try again in a minute.</span>")
|
||||
/datum/preferences/proc/SetQuirks(mob/user)
|
||||
if(!SSquirks)
|
||||
to_chat(user, "<span class='danger'>The quirk subsystem is still initializing! Try again in a minute.</span>")
|
||||
return
|
||||
|
||||
var/list/dat = list()
|
||||
if(!SStraits.traits.len)
|
||||
dat += "The trait subsystem hasn't finished initializing, please hold..."
|
||||
if(!SSquirks.quirks.len)
|
||||
dat += "The quirk subsystem hasn't finished initializing, please hold..."
|
||||
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>"
|
||||
|
||||
else
|
||||
dat += "<center><b>Choose trait 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>\
|
||||
Traits are applied at roundstart and cannot normally be removed.</div>"
|
||||
dat += "<center><b>Choose quirk setup</b></center><br>"
|
||||
dat += "<div align='center'>Left-click to add or remove quirks. You need negative quirks to have positive ones.<br>\
|
||||
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 += "<hr>"
|
||||
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
|
||||
dat += "<center>[all_traits.len] / [MAX_TRAITS] max traits<br>\
|
||||
<b>Trait balance remaining:</b> [GetTraitBalance()]</center><br>"
|
||||
for(var/V in SStraits.traits)
|
||||
var/datum/trait/T = SStraits.traits[V]
|
||||
var/trait_name = initial(T.name)
|
||||
var/has_trait
|
||||
var/trait_cost = initial(T.value) * -1
|
||||
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
|
||||
dat += "<center>[all_quirks.len] / [MAX_QUIRKS] max quirks<br>\
|
||||
<b>Quirk balance remaining:</b> [GetQuirkBalance()]</center><br>"
|
||||
for(var/V in SSquirks.quirks)
|
||||
var/datum/quirk/T = SSquirks.quirks[V]
|
||||
var/quirk_name = initial(T.name)
|
||||
var/has_quirk
|
||||
var/quirk_cost = initial(T.value) * -1
|
||||
var/lock_reason = "This trait is unavailable."
|
||||
var/trait_conflict = FALSE
|
||||
for(var/_V in all_traits)
|
||||
if(_V == trait_name)
|
||||
has_trait = TRUE
|
||||
if(initial(T.mood_trait) && CONFIG_GET(flag/disable_human_mood))
|
||||
var/quirk_conflict = FALSE
|
||||
for(var/_V in all_quirks)
|
||||
if(_V == quirk_name)
|
||||
has_quirk = TRUE
|
||||
if(initial(T.mood_quirk) && CONFIG_GET(flag/disable_human_mood))
|
||||
lock_reason = "Mood is disabled."
|
||||
trait_conflict = TRUE
|
||||
if(has_trait)
|
||||
if(trait_conflict)
|
||||
all_traits -= trait_name
|
||||
has_trait = FALSE
|
||||
quirk_conflict = TRUE
|
||||
if(has_quirk)
|
||||
if(quirk_conflict)
|
||||
all_quirks -= quirk_name
|
||||
has_quirk = FALSE
|
||||
else
|
||||
trait_cost *= -1 //invert it back, since we'd be regaining this amount
|
||||
if(trait_cost > 0)
|
||||
trait_cost = "+[trait_cost]"
|
||||
quirk_cost *= -1 //invert it back, since we'd be regaining this amount
|
||||
if(quirk_cost > 0)
|
||||
quirk_cost = "+[quirk_cost]"
|
||||
var/font_color = "#AAAAFF"
|
||||
if(initial(T.value) != 0)
|
||||
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
|
||||
if(trait_conflict)
|
||||
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \
|
||||
if(quirk_conflict)
|
||||
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
|
||||
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
|
||||
else
|
||||
if(has_trait)
|
||||
dat += "<b><font color='[font_color]'>[trait_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>"
|
||||
if(has_quirk)
|
||||
dat += "<b><font color='[font_color]'>[quirk_name]</font></b> - [initial(T.desc)] \
|
||||
<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
|
||||
else
|
||||
dat += "<font color='[font_color]'>[trait_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>"
|
||||
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
|
||||
<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>"
|
||||
|
||||
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_content(dat.Join())
|
||||
popup.open(0)
|
||||
return
|
||||
|
||||
/datum/preferences/proc/GetTraitBalance()
|
||||
/datum/preferences/proc/GetQuirkBalance()
|
||||
var/bal = 0
|
||||
for(var/V in all_traits)
|
||||
var/datum/trait/T = SStraits.traits[V]
|
||||
for(var/V in all_quirks)
|
||||
var/datum/quirk/T = SSquirks.quirks[V]
|
||||
bal -= initial(T.value)
|
||||
return bal
|
||||
|
||||
@@ -981,55 +981,55 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
user << browse(null, "window=mob_occupation")
|
||||
ShowChoices(user)
|
||||
if("update")
|
||||
var/trait = href_list["trait"]
|
||||
if(!SStraits.traits[trait])
|
||||
var/quirk = href_list["trait"]
|
||||
if(!SSquirks.quirks[quirk])
|
||||
return
|
||||
var/value = SStraits.trait_points[trait]
|
||||
var/value = SSquirks.quirk_points[quirk]
|
||||
if(value == 0)
|
||||
if(trait in neutral_traits)
|
||||
neutral_traits -= trait
|
||||
all_traits -= trait
|
||||
if(quirk in neutral_quirks)
|
||||
neutral_quirks -= quirk
|
||||
all_quirks -= quirk
|
||||
else
|
||||
if(all_traits.len >= MAX_TRAITS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
||||
if(all_quirks.len >= MAX_QUIRKS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
|
||||
return
|
||||
neutral_traits += trait
|
||||
all_traits += trait
|
||||
neutral_quirks += quirk
|
||||
all_quirks += quirk
|
||||
else
|
||||
var/balance = GetTraitBalance()
|
||||
if(trait in positive_traits)
|
||||
positive_traits -= trait
|
||||
all_traits -= trait
|
||||
else if(trait in negative_traits)
|
||||
var/balance = GetQuirkBalance()
|
||||
if(quirk in positive_quirks)
|
||||
positive_quirks -= quirk
|
||||
all_quirks -= quirk
|
||||
else if(quirk in negative_quirks)
|
||||
if(balance + value < 0)
|
||||
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
|
||||
return
|
||||
negative_traits -= trait
|
||||
all_traits -= trait
|
||||
negative_quirks -= quirk
|
||||
all_quirks -= quirk
|
||||
else if(value > 0)
|
||||
if(all_traits.len >= MAX_TRAITS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
||||
if(all_quirks.len >= MAX_QUIRKS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
|
||||
return
|
||||
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
|
||||
positive_traits += trait
|
||||
all_traits += trait
|
||||
positive_quirks += quirk
|
||||
all_quirks += quirk
|
||||
else
|
||||
if(all_traits.len >= MAX_TRAITS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
||||
if(all_quirks.len >= MAX_QUIRKS)
|
||||
to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] quirks!</span>")
|
||||
return
|
||||
negative_traits += trait
|
||||
all_traits += trait
|
||||
SetTraits(user)
|
||||
negative_quirks += quirk
|
||||
all_quirks += quirk
|
||||
SetQuirks(user)
|
||||
if("reset")
|
||||
all_traits = list()
|
||||
positive_traits = list()
|
||||
negative_traits = list()
|
||||
neutral_traits = list()
|
||||
SetTraits(user)
|
||||
all_quirks = list()
|
||||
positive_quirks = list()
|
||||
negative_quirks = list()
|
||||
neutral_quirks = list()
|
||||
SetQuirks(user)
|
||||
else
|
||||
SetTraits(user)
|
||||
SetQuirks(user)
|
||||
return TRUE
|
||||
|
||||
switch(href_list["task"])
|
||||
|
||||
@@ -313,11 +313,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["job_engsec_med"] >> job_engsec_med
|
||||
S["job_engsec_low"] >> job_engsec_low
|
||||
|
||||
//Traits
|
||||
S["all_traits"] >> all_traits
|
||||
S["positive_traits"] >> positive_traits
|
||||
S["negative_traits"] >> negative_traits
|
||||
S["neutral_traits"] >> neutral_traits
|
||||
//Quirks
|
||||
S["all_quirks"] >> all_quirks
|
||||
S["positive_quirks"] >> positive_quirks
|
||||
S["negative_quirks"] >> negative_quirks
|
||||
S["neutral_quirks"] >> neutral_quirks
|
||||
|
||||
//Citadel code
|
||||
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_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
|
||||
|
||||
all_traits = SANITIZE_LIST(all_traits)
|
||||
positive_traits = SANITIZE_LIST(positive_traits)
|
||||
negative_traits = SANITIZE_LIST(negative_traits)
|
||||
neutral_traits = SANITIZE_LIST(neutral_traits)
|
||||
all_quirks = SANITIZE_LIST(all_quirks)
|
||||
positive_quirks = SANITIZE_LIST(positive_quirks)
|
||||
negative_quirks = SANITIZE_LIST(negative_quirks)
|
||||
neutral_quirks = SANITIZE_LIST(neutral_quirks)
|
||||
|
||||
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_low"] , job_engsec_low)
|
||||
|
||||
//Traits
|
||||
WRITE_FILE(S["all_traits"] , all_traits)
|
||||
WRITE_FILE(S["positive_traits"] , positive_traits)
|
||||
WRITE_FILE(S["negative_traits"] , negative_traits)
|
||||
WRITE_FILE(S["neutral_traits"] , neutral_traits)
|
||||
//Quirks
|
||||
WRITE_FILE(S["all_quirks"] , all_quirks)
|
||||
WRITE_FILE(S["positive_quirks"] , positive_quirks)
|
||||
WRITE_FILE(S["negative_quirks"] , negative_quirks)
|
||||
WRITE_FILE(S["neutral_quirks"] , neutral_quirks)
|
||||
|
||||
cit_character_pref_save(S)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/blood_type = null
|
||||
var/list/features = null
|
||||
var/factions = null
|
||||
var/list/traits = null
|
||||
var/list/quirks = null
|
||||
var/contains_sample = 0
|
||||
|
||||
/obj/item/seeds/replicapod/Initialize()
|
||||
@@ -42,7 +42,7 @@
|
||||
blood_type = B.data["blood_type"]
|
||||
features = B.data["features"]
|
||||
factions = B.data["factions"]
|
||||
factions = B.data["traits"]
|
||||
factions = B.data["quirks"]
|
||||
contains_sample = TRUE
|
||||
visible_message("<span class='notice'>The [src] is injected with a fresh blood sample.</span>")
|
||||
else
|
||||
@@ -114,7 +114,7 @@
|
||||
podman.faction |= factions
|
||||
if(!features["mcolor"])
|
||||
features["mcolor"] = "#59CE00"
|
||||
for(var/V in traits)
|
||||
for(var/V in quirks)
|
||||
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.set_cloned_appearance()
|
||||
|
||||
@@ -400,7 +400,7 @@
|
||||
SSticker.mode.make_antag_chance(humanc)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -193,10 +193,10 @@
|
||||
blood_data["real_name"] = real_name
|
||||
blood_data["features"] = dna.features
|
||||
blood_data["factions"] = faction
|
||||
blood_data["traits"] = list()
|
||||
for(var/V in roundstart_traits)
|
||||
var/datum/trait/T = V
|
||||
blood_data["traits"] += T.type
|
||||
blood_data["quirks"] = list()
|
||||
for(var/V in roundstart_quirks)
|
||||
var/datum/quirk/T = V
|
||||
blood_data["quirks"] += T.type
|
||||
return blood_data
|
||||
|
||||
//get the id of the substance this mob use as blood.
|
||||
|
||||
@@ -733,8 +733,8 @@
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
to_chat(src, "<span class='danger'>You're starving!</span>")
|
||||
|
||||
if(roundstart_traits.len)
|
||||
to_chat(src, "<span class='notice'>You have these traits: [get_trait_string()].</span>")
|
||||
if(roundstart_quirks.len)
|
||||
to_chat(src, "<span class='notice'>You have these quirks: [get_trait_string()].</span>")
|
||||
else
|
||||
if(wear_suit)
|
||||
wear_suit.add_fingerprint(M)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -146,12 +146,12 @@
|
||||
else
|
||||
status_traits[trait] |= list(source)
|
||||
|
||||
/mob/living/proc/add_trait_datum(trait, spawn_effects) //separate proc due to the way these ones are handled
|
||||
if(has_trait(trait))
|
||||
/mob/living/proc/add_quirk(quirk, spawn_effects) //separate proc due to the way these ones are handled
|
||||
if(has_trait(quirk))
|
||||
return
|
||||
if(!SStraits || !SStraits.traits[trait])
|
||||
if(!SSquirks || !SSquirks.quirks[quirk])
|
||||
return
|
||||
var/datum/trait/T = SStraits.traits[trait]
|
||||
var/datum/quirk/T = SSquirks.quirks[quirk]
|
||||
new T (src, spawn_effects)
|
||||
return TRUE
|
||||
|
||||
@@ -180,8 +180,8 @@
|
||||
if(!LAZYLEN(status_traits[trait]))
|
||||
status_traits -= trait
|
||||
|
||||
/mob/living/proc/remove_trait_datum(trait)
|
||||
var/datum/trait/T = roundstart_traits[trait]
|
||||
/mob/living/proc/remove_quirk(quirk)
|
||||
var/datum/quirk/T = roundstart_quirks[quirk]
|
||||
if(T)
|
||||
qdel(T)
|
||||
return TRUE
|
||||
@@ -201,8 +201,8 @@
|
||||
else if(LAZYLEN(status_traits[trait]))
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/has_trait_datum(trait)
|
||||
return roundstart_traits[trait]
|
||||
/mob/living/proc/has_quirk(quirk)
|
||||
return roundstart_quirks[quirk]
|
||||
|
||||
/mob/living/proc/remove_all_traits()
|
||||
status_traits = list()
|
||||
|
||||
@@ -536,7 +536,8 @@ ALLOW_MISCREANTS
|
||||
## Determines if players are allowed to print integrated circuits, uncomment to allow.
|
||||
#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
|
||||
|
||||
## Uncomment to disable human moods.
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
// Citadel-specific Neutral Traits
|
||||
|
||||
/datum/trait/libido
|
||||
/datum/quirk/libido
|
||||
name = "Nymphomania"
|
||||
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
|
||||
value = 0
|
||||
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>"
|
||||
|
||||
/datum/trait/libido/add()
|
||||
var/mob/living/M = trait_holder
|
||||
/datum/quirk/libido/add()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = 16
|
||||
M.arousal_rate = 3
|
||||
|
||||
/datum/trait/libido/remove()
|
||||
var/mob/living/M = trait_holder
|
||||
/datum/quirk/libido/remove()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = initial(M.min_arousal)
|
||||
M.arousal_rate = initial(M.arousal_rate)
|
||||
|
||||
/datum/trait/libido/on_process()
|
||||
var/mob/living/M = trait_holder
|
||||
/datum/quirk/libido/on_process()
|
||||
var/mob/living/M = quirk_holder
|
||||
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)
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
#include "code\controllers\subsystem\processing\obj.dm"
|
||||
#include "code\controllers\subsystem\processing\processing.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\datums\action.dm"
|
||||
#include "code\datums\ai_laws.dm"
|
||||
@@ -445,7 +445,7 @@
|
||||
#include "code\datums\status_effects\gas.dm"
|
||||
#include "code\datums\status_effects\neutral.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\negative.dm"
|
||||
#include "code\datums\traits\neutral.dm"
|
||||
|
||||
Reference in New Issue
Block a user