Files
2020-02-19 19:48:29 -08:00

970 lines
27 KiB
Plaintext

//Unlockable traits? tied to achievements?
#define TRAIT_STARTING_POINTS 1 //How many "free" points you get
#define TRAIT_MAX 6 //How many traits people can select at most.
/proc/getTraitById(var/id)
return traitList[id]
/proc/traitCategoryAllowed(var/list/targetList, var/idToCheck)
var/obj/trait/C = getTraitById(idToCheck)
if(C.category == null) return 1
for(var/A in targetList)
var/obj/trait/T = getTraitById(A)
if(T.category == C.category) return 0
return 1
/datum/traitPreferences
var/list/traits_selected = list()
var/point_total = TRAIT_STARTING_POINTS
var/free_points = TRAIT_STARTING_POINTS
proc/selectTrait(var/id)
if(!traits_selected.Find(id) && traitList.Find(id))
traits_selected.Add(id)
calcTotal()
return 1
proc/unselectTrait(var/id)
if(traits_selected.Find(id))
traits_selected.Remove(id)
calcTotal()
return 1
proc/calcTotal()
var/sum = free_points
for(var/T in traits_selected)
if(traitList.Find(T))
var/obj/trait/O = traitList[T]
sum += O.points
point_total = sum
return sum
proc/isValid()
var/list/categories = list()
for(var/A in traits_selected)
var/obj/trait/T = getTraitById(A)
if(T.unselectable) return 0
//if(T.requiredUnlock != null && usr.client) //This will likely fail since the unlocks will not have loaded by the time the trait preferences are created. getscores is too slow.
// if(usr.client.qualifiedXpRewards != null)
// if(!usr.client.qualifiedXpRewards.Find(T.requiredUnlock))
// return 0
if(T.category != null)
if(categories.Find(T.category)) return 0
else categories.Add(T.category)
return (calcTotal() >= 0)
proc/updateTraits(var/mob/user)
if(!winexists(user, "traitssetup_[user.ckey]"))
winclone(user, "traitssetup", "traitssetup_[user.ckey]")
var/list/selected = list()
var/list/available = list()
var/skipUnlocks = 0
for(var/X in traitList)
var/obj/trait/C = getTraitById(X)
if(C.unselectable) continue
if(C.requiredUnlock != null && skipUnlocks) continue
if(C.requiredUnlock != null && user.client) //If this needs an xp unlock, check against the pre-generated list of related xp unlocks for this person.
if(user.client.qualifiedXpRewards != null)
if(!user.client.qualifiedXpRewards.Find(C.requiredUnlock))
continue
else
boutput(user, "<span style=\"color:red\"><b>WARNING: XP unlocks failed to update. Some traits may not be available. Please try again in a moment.</b></span>")
SPAWN_DBG(0) user.client.updateXpRewards()
skipUnlocks = 1
continue
if(traits_selected.Find(X)) selected += X
else available += X
winset(user, "traitssetup_[user.ckey].traitsSelected", "cells=\"1x[selected.len]\"")
var/countSel = 0
for(var/S in selected)
winset(user, "traitssetup_[user.ckey].traitsSelected", "current-cell=1,[++countSel]")
user << output(traitList[S], "traitssetup_[user.ckey].traitsSelected")
winset(user, "traitssetup_[user.ckey].traitsAvailable", "cells=\"1x[available.len]\"")
var/countAvail = 0
for(var/A in available)
winset(user, "traitssetup_[user.ckey].traitsAvailable", "current-cell=1,[++countAvail]")
user << output(traitList[A], "traitssetup_[user.ckey].traitsAvailable")
winset(user, "traitssetup_[user.ckey].traitPoints", "text=\"Points left : [calcTotal()]\"&text-color=\"[calcTotal() > 0 ? "#00AA00" : "#AA0000"]\"")
return
proc/showTraits(var/mob/user)
if(!winexists(user, "traitssetup_[user.ckey]"))
winclone(user, "traitssetup", "traitssetup_[user.ckey]")
winshow(user, "traitssetup_[user.ckey]")
updateTraits(user)
user.Browse(null, "window=preferences")
return
/datum/traitHolder
var/list/traits = list()
var/list/moveTraits = list() // differentiate movement traits for Move()
var/mob/owner = null
New(var/mob/ownerMob)
owner = ownerMob
return ..()
proc/addTrait(id)
if(!traits.Find(id) && owner)
traits.Add(id)
var/obj/trait/T = traitList[id]
if(T.isMoveTrait)
moveTraits.Add(id)
T.onAdd(owner)
return
proc/removeTrait(id)
if(traits.Find(id) && owner)
traits.Remove(id)
var/obj/trait/T = traitList[id]
if(T.isMoveTrait)
moveTraits.Remove(id)
T.onRemove(owner)
return
proc/removeAll()
for (var/obj/trait/T in traits)
traits.Remove(T.id)
if(T.isMoveTrait)
moveTraits.Remove(T.id)
T.onRemove(owner)
proc/hasTrait(var/id)
return traits.Find(id)
//Yes these are objs because grid control. Shut up. I don't like it either.
/obj/trait
icon = 'icons/ui/traits.dmi'
icon_state = "placeholder"
var/id = "" //Unique ID
var/points = 0 //The change in points when this is selected.
var/isPositive = 1 //Is this a positive, good effect or a bad one.
var/category = null //If set to a non-null string, People will only be able to pick one trait of any given category
var/unselectable = 0 //If 1 , trait can not be select at char setup
var/requiredUnlock = null //If set to a string, the xp unlock of that name is required for this to be selectable.
var/cleanName = "" //Name without any additional information.
var/isMoveTrait = 0 // If 1, onMove will be called each movement step from the holder's mob
proc/onAdd(var/mob/owner)
return
proc/onRemove(var/mob/owner)
return
proc/onLife(var/mob/owner)
return
proc/onMove(var/mob/owner)
return
Click(location,control,params)
if(control)
if(control == "traitssetup_[usr.ckey].traitsAvailable")
if(!usr.client.preferences.traitPreferences.traits_selected.Find(id))
if(traitCategoryAllowed(usr.client.preferences.traitPreferences.traits_selected, id))
if(usr.client.preferences.traitPreferences.traits_selected.len >= TRAIT_MAX)
alert(usr, "You can not select more than [TRAIT_MAX] traits.")
else
if(((usr.client.preferences.traitPreferences.calcTotal()) + points) < 0)
alert(usr, "You do not have enough points available to select this trait.")
else
usr.client.preferences.traitPreferences.selectTrait(id)
else
alert(usr, "You can only select one trait of this category.")
else if (control == "traitssetup_[usr.ckey].traitsSelected")
if(usr.client.preferences.traitPreferences.traits_selected.Find(id))
if(((usr.client.preferences.traitPreferences.calcTotal()) - points) < 0)
alert(usr, "Removing this trait would leave you with less than 0 points. Please remove a different trait.")
else
usr.client.preferences.traitPreferences.unselectTrait(id)
usr.client.preferences.traitPreferences.updateTraits(usr)
return
MouseEntered(location,control,params)
if(winexists(usr, "traitssetup_[usr.ckey]"))
winset(usr, "traitssetup_[usr.ckey].traitName", "text=\"[name]\"")
winset(usr, "traitssetup_[usr.ckey].traitDesc", "text=\"[desc]\"")
return
// BODY - Red Border
/obj/trait/roboarms
name = "Robotic arms (0) \[Body\]"
cleanName = "Robotic arms"
desc = "Your arms have been replaced with light robotic arms."
id = "roboarms"
icon_state = "robotarmsR"
points = 0
isPositive = 1
category = "body"
onAdd(var/mob/owner)
SPAWN_DBG(4 SECONDS) //Fuck this. Fuck the way limbs are added with a delay. FUCK IT
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.limbs != null)
H.limbs.replace_with("l_arm", /obj/item/parts/robot_parts/arm/left/light, null , 0)
H.limbs.replace_with("r_arm", /obj/item/parts/robot_parts/arm/right/light, null , 0)
H.limbs.l_arm.holder = H
H.limbs.r_arm.holder = H
H.update_body()
return
/obj/trait/syntharms
name = "Green Fingers (-2) \[Body\]"
cleanName = "Green Fingers"
desc = "Excess exposure to radiation, mutagen and gardening have turned your arms into plants. The horror!"
id = "syntharms"
icon_state = "robotarmsR"
points = -2
isPositive = 0
category = "body"
onAdd(var/mob/owner)
SPAWN_DBG(4 SECONDS)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.limbs != null)
H.limbs.replace_with("l_arm", pick(/obj/item/parts/human_parts/arm/left/synth/bloom, /obj/item/parts/human_parts/arm/left/synth), null , 0)
H.limbs.replace_with("r_arm", pick(/obj/item/parts/human_parts/arm/right/synth/bloom, /obj/item/parts/human_parts/arm/right/synth), null , 0)
H.limbs.l_arm.holder = H
H.limbs.r_arm.holder = H
H.update_body()
return
/obj/trait/explolimbs
name = "Adamantium Skeleton (-2) \[Body\]"
cleanName = "Adamantium Skeleton"
desc = "Halves the chance that an explosion will blow off your limbs."
id = "explolimbs"
category = "body"
points = -2
isPositive = 1
/obj/trait/deaf
name = "Deaf (+1) \[Body\]"
cleanName = "Deaf"
desc = "Spawn with permanent deafness and an auditory headset."
id = "deaf"
category = "body"
points = 1
isPositive = 0
onAdd(var/mob/owner)
if(owner.bioHolder)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
owner.bioHolder.AddEffect("deaf", 0, 0, 0, 1)
H.equip_if_possible(new /obj/item/device/radio/headset/deaf(H), H.slot_ears)
return
onLife(var/mob/owner) //Just to be super safe.
if(!owner.ear_disability)
owner.bioHolder.AddEffect("deaf", 0, 0, 0, 1)
return
// LANGUAGE - Yellow Border
/obj/trait/swedish
name = "Swedish (0) \[Language\]"
cleanName = "Swedish"
desc = "You are from sweden. Meat balls and so on."
id = "swedish"
icon_state = "swedenY"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_swedish", 0, 0, 0, 1)
return
/obj/trait/french
name = "French (0) \[Language\]"
cleanName = "French"
desc = "You are from Quebec. y'know, the other Canada."
id = "french"
icon_state = "frY"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_french", 0, 0, 0, 1)
return
/obj/trait/scots
name = "Scots (0) \[Language\]"
cleanName = "Scottish"
desc = "Hear the pipes are calling, down thro' the glen. Och aye!"
id = "scottish"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_scots", 0, 0, 0, 1)
return
/obj/trait/chav
name = "Chav (0) \[Language\]"
cleanName = "Chav"
desc = "U wot m8? I sware i'll fite u."
id = "chav"
icon_state = "ukY"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_chav", 0, 0, 0, 1)
return
/obj/trait/elvis
name = "Funky Accent (0) \[Language\]"
cleanName = "Funky Accent"
desc = "Give a man a banana and he will clown for a day. Teach a man to clown and he will live in a cold dark corner of a space station for the rest of his days. - Elvis, probably."
id = "elvis"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_elvis", 0, 0, 0, 1)
return
/obj/trait/tommy // please do not re-enable this without talking to spy tia
name = "New Jersey Accent (0) \[Language\]"
cleanName = "New Jersey Accent"
desc = "Ha ha ha. What a story, Mark."
id = "tommy"
icon_state = "whatY"
points = 0
// isPositive = 1
category = "language"
unselectable = 1 // this was not supposed to be a common thing!!
/*
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_tommy")
return
*/
/obj/trait/finnish
name = "Finnish Accent (0) \[Language\]"
cleanName = "Finnish Accent"
desc = "...and you thought space didn't have Finns?"
id = "finnish"
icon_state = "finnish"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_finnish", 0, 0, 0, 1)
return
// VISION/SENSES - Green Border
/obj/trait/cateyes
name = "Cat eyes (-1) \[Vision\]"
cleanName = "Cat eyes"
desc = "You can see 2 tiles further in the dark."
id = "cateyes"
icon_state = "catseyeG"
points = -1
isPositive = 1
category = "vision"
/obj/trait/infravision
name = "Infravision (-1) \[Vision\]"
cleanName = "Infravision"
desc = "You can always see messages written in infra-red ink."
id = "infravision"
icon_state = "infravisionG"
points = -1
isPositive = 0
category = "vision"
/obj/trait/shortsighted
name = "Short-sighted (+1) \[Vision\]"
cleanName = "Short-sighted"
desc = "Spawn with permanent short-sightedness and glasses."
id = "shortsighted"
icon_state = "glassesG"
category = "vision"
points = 1
isPositive = 0
onAdd(var/mob/owner)
if(owner.bioHolder)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
owner.bioHolder.AddEffect("bad_eyesight", 0, 0, 0, 1)
H.equip_if_possible(new /obj/item/clothing/glasses/regular(H), H.slot_glasses)
return
onLife(var/mob/owner) //Just to be super safe.
if(owner.bioHolder && !owner.bioHolder.HasEffect("bad_eyesight"))
owner.bioHolder.AddEffect("bad_eyesight", 0, 0, 0, 1)
return
/obj/trait/blind
name = "Blind (+2)"
cleanName = "Blind"
desc = "Spawn with permanent blindness and a VISOR."
id = "blind"
category = "vision"
points = 2
isPositive = 0
onAdd(var/mob/owner)
if(owner.bioHolder)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
owner.bioHolder.AddEffect("blind", 0, 0, 0, 1)
H.equip_if_possible(new /obj/item/clothing/glasses/visor(H), H.slot_glasses)
return
onLife(var/mob/owner) //Just to be safe.
if(owner.bioHolder && !owner.bioHolder.HasEffect("blind"))
owner.bioHolder.AddEffect("blind", 0, 0, 0, 1)
return
// GENETICS - Blue Border
/obj/trait/robustgenetics
name = "Robust Genetics (-2) \[Genetics\]"
cleanName = "Robust Genetics"
desc = "You gain an additional 20 genetic stability."
id = "robustgenetics"
icon_state = "stablegenesB"
points = -2
isPositive = 0
category = "genetics"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.genetic_stability = 120
return
/obj/trait/stablegenes
name = "Stable Genes (-2) \[Genetics\]"
cleanName = "Stable Genes"
desc = "You are less likely to mutate from radiation or mutagens."
id = "stablegenes"
icon_state = "dontmutateB"
points = -2
isPositive = 0
category = "genetics"
// TRINKETS/ITEMS - Purple Border
/obj/trait/loyalist
name = "NT loyalist (-1) \[Trinkets\]"
cleanName = "NT loyalist"
desc = "Start with a Nanotrasen Beret as your trinket."
id = "loyalist"
icon_state = "beretP"
points = -1
isPositive = 1
category = "trinkets"
/obj/trait/petasusaphilic
name = "Petasusaphilic (-1) \[Trinkets\]"
cleanName = "Petasusaphilic"
desc = "Start with a random hat as your trinket."
id = "petasusaphilic"
icon_state = "hatP"
points = -1
isPositive = 1
category = "trinkets"
/obj/trait/pawnstar
name = "Pawn Star (-1) \[Trinkets\]"
cleanName = "Pawn Star"
desc = "You sold your trinket before you departed for the station. You start with a bonus of 25% of your starting cash in your inventory."
id = "pawnstar"
icon_state = "pawnP"
points = -1
isPositive = 1
category = "trinkets"
/obj/trait/beestfriend
name = "BEEst friend (-1) \[Trinkets\]"
cleanName = "BEEst friend"
desc = "Start with a bee egg as your trinket."
id = "beestfriend"
points = -1
isPositive = 1
category = "trinkets"
// Skill - Undetermined Border
/obj/trait/smoothtalker
name = "Smooth talker (-1) \[Skill\]"
cleanName = "Smooth talker"
desc = "Traders will tolerate 50% more when you are haggling with them."
id = "smoothtalker"
category = "skill"
points = -1
isPositive = 1
/obj/trait/matrixflopout
name = "Matrix Flopout (-2) \[Skill\]"
cleanName = "Matrix Flopout"
desc = "Flipping lets you dodge bullets and attacks for a higher stamina cost!"
id = "matrixflopout"
category = "skill"
points = -2
isPositive = 1
/obj/trait/happyfeet
name = "Happyfeet (-1) \[Skill\]"
cleanName = "Happyfeet"
desc = "Sometimes people can't help but dance along with you."
id = "happyfeet"
category = "skill"
points = -1
isPositive = 1
/* Hey dudes, I moved these over from the old bioEffect/Genetics system so they work on clone */
/obj/trait/job
name = "hi yes I'm a bug"
desc = "This is an error! Please report this to coders. May cause pointed questions towards the affected!"
id = "error"
points = 0
isPositive = 1
unselectable = 1
category = "job"
onAdd(var/mob/owner)
return
onLife(var/mob/owner) //Just to be safe.
return
/obj/trait/job/chaplain
name = "Chaplain Training"
cleanName = "Chaplain Training"
desc = "Subject is trained in cultural and psychological matters."
id = "training_chaplain"
/obj/trait/job/medical
name = "Medical Training"
cleanName = "Medical Training"
desc = "Subject is a proficient surgeon."
id = "training_medical"
/obj/trait/job/security
name = "Security Training"
cleanName = "Security Training"
desc = "Subject is trained in generalized robustness and asskicking."
id = "training_security"
// barman, detective, HoS
/obj/trait/job/drinker
name = "Professional Drinker"
cleanName = "Professional Drinker"
desc = "Sometimes you drink on the job, sometimes drinking is the job."
id = "training_drinker"
// Phobias - Undetermined Border
/obj/trait/phobia
name = "Phobias suck"
desc = "Wow, phobias are no fun! Report this to a coder please."
unselectable = 1
/obj/trait/phobia/space
name = "Spacephobia (+1) \[Phobia\]"
cleanName = "Spacephobia"
desc = "Being in space scares you. A lot. While in space you might panic or faint."
id = "spacephobia"
points = 1
isPositive = 0
onLife(var/mob/owner)
if(!owner.stat && can_act(owner) && istype(owner.loc, /turf/space))
if(prob(2))
owner.emote("faint")
owner.changeStatus("paralysis", 80)
else if (prob(8))
owner.emote("scream")
owner.changeStatus("stunned", 2 SECONDS)
return
// Stats - Undetermined Border
/obj/trait/meathead
name = "Meathead (-1) \[Stats\]"
cleanName = "Meathead"
desc = "You can take quite a beating! You suffer from brain trauma, though."
id = "meathead"
category = "stats"
points = -1
isPositive = 1
onAdd(var/mob/owner)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
H.max_health = 150
H.health = 150
H.brainloss = 60
return
onLife(var/mob/owner) //Just to be safe.
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
H.max_health = 150
if(H.brainloss < 60)
H.brainloss = 60
return
/obj/trait/athletic
name = "Athletic (-2) \[Stats\]"
cleanName = "Athletic"
desc = "Great stamina! Frail body."
id = "athletic"
category = "stats"
points = -2
isPositive = 1
onAdd(var/mob/owner)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
H.add_stam_mod_max("trait", STAMINA_MAX * 0.1)
H.add_stam_mod_regen("trait", STAMINA_REGEN * 0.1)
H.max_health = 60
H.health = 60
return
/obj/trait/bigbruiser
name = "Big Bruiser (-2) \[Stats\]"
cleanName = "Big Bruiser"
desc = "Stronger punches but higher stamina cost!"
id = "bigbruiser"
category = "stats"
points = -2
isPositive = 1
// NO CATEGORY - Grey Border
/obj/trait/hemo
name = "Hemophilia (+1)"
cleanName = "Hemophilia"
desc = "You bleed more easily and you bleed more."
id = "hemophilia"
points = 1
isPositive = 0
/obj/trait/slowmetabolism
name = "Slow Metabolism (0)"
cleanName = "Slow Metabolism"
desc = "Any chemicals in you body deplete much more slowly."
id = "slowmetabolism"
points = 0
isPositive = 1
/obj/trait/alcoholic
name = "Career alcoholic (0)"
cleanName = "Career alcoholic"
desc = "You gain alcohol resistance but your speech is permanently slurred."
id = "alcoholic"
icon_state = "beer"
points = 0
isPositive = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("resist_alcohol", 0, 0, 0, 1)
return
/obj/trait/random_allergy
name = "Allergy (+0)"
cleanName = "Allergy"
desc = "You're allergic to... something. You can't quite remember, but how bad could it possibly be?"
id = "randomallergy"
points = 0
isPositive = 0
var/allergen = ""
var/allergen_name = ""
var/list/allergen_id_list = list("spaceacillin","morphine","teporone","salicylic_acid","calomel","synthflesh","omnizine","saline","anti_rad","smelling_salt",\
"haloperidol","epinephrine","insulin","silver_sulfadiazine","mutadone","ephedrine","penteticacid","antihistamine","stypic_powder","cryoxadone","atropine",\
"salbutamol","perfluorodecalin","mannitol","charcoal","antihol","ethanol","iron","mercury","oxygen","plasma","sugar","radium","water","bathsalts","jenkem","crank",\
"LSD","space_drugs","THC","nicotine","krokodil","catdrugs","triplemeth","methamphetamine","mutagen","neurotoxin","sarin","smokepowder","infernite","napalm", "fuel",\
"anti_fart","lube","ectoplasm","cryostylane","oil","sewage","ants","spiders","poo","love","hugs","fartonium","blood","bloodc","vomit","urine","capsaicin","cheese",\
"coffee","chocolate","chickensoup","salt","grease","badgrease","msg","egg")
onAdd(var/mob/owner)
allergen = pick(allergen_id_list)
if (reagents_cache.len <= 0)
build_reagent_cache()
var/datum/reagent/R = reagents_cache[allergen]
if(R)
allergen_name = R.name
else
throw EXCEPTION("Could not find reagent for id:[allergen]")
onLife(var/mob/owner)
if (owner.reagents.has_reagent(allergen))
owner.reagents.add_reagent("histamine", 1.4) //1.4 units of histamine per life cycle? is that too much?
/obj/trait/random_allergy/medical_allergy
name = "Medical Allergy (+1)"
cleanName = "Medical Allergy"
desc = "You're allergic to some medical chemical... but you can't remember which."
id = "medicalallergy"
points = 1
allergen_id_list = list("spaceacillin","morphine","teporone","salicylic_acid","calomel","synthflesh","omnizine","saline","anti_rad","smelling_salt",\
"haloperidol","epinephrine","insulin","silver_sulfadiazine","mutadone","ephedrine","penteticacid","antihistamine","stypic_powder","cryoxadone","atropine",\
"salbutamol","perfluorodecalin","mannitol","charcoal","antihol")
/obj/trait/addict
name = "Addict (+2)"
cleanName = "Addict"
desc = "You spawn with a random addiction. Once cured there is a small chance that you will suffer a relapse."
id = "addict"
icon_state = "syringe"
points = 2
isPositive = 0
var/selected_reagent = "ethanol"
New()
selected_reagent = pick("bath salts", "lysergic acid diethylamide", "space drugs", "psilocybin", "cat drugs", "methamphetamine")
. = ..()
onAdd(var/mob/owner)
if(ishuman(owner))
addAddiction(owner)
return
onLife(var/mob/owner) //Just to be safe.
if(ishuman(owner) && prob(1))
var/mob/living/carbon/human/M = owner
for(var/datum/ailment_data/addiction/A in M.ailments)
if(istype(A, /datum/ailment_data/addiction))
if(A.associated_reagent == selected_reagent) return
addAddiction(owner)
return
proc/addAddiction(var/mob/owner)
var/mob/living/carbon/human/M = owner
var/datum/ailment_data/addiction/AD = new
AD.associated_reagent = selected_reagent
AD.last_reagent_dose = world.timeofday
AD.name = "[selected_reagent] addiction"
AD.affected_mob = M
M.ailments += AD
return
/obj/trait/strongwilled
name = "Strong willed (-1)"
cleanName = "Strong willed"
desc = "You are more resistant to addiction."
id = "strongwilled"
icon_state = "nosmoking"
points = -1
isPositive = 1
/obj/trait/addictive_personality // different than addict because you just have a general weakness to addictions instead of starting with a specific one
name = "Addictive Personality (+1)"
cleanName = "Addictive Personality"
desc = "You are less resistant to addiction."
id = "addictive_personality"
icon_state = "syringe"
points = 1
isPositive = 0
/obj/trait/unionized
name = "Unionized (-1)"
cleanName = "Unionized"
desc = "You start with a higher paycheck than normal."
id = "unionized"
icon_state = "handshake"
points = -1
isPositive = 1
/obj/trait/jailbird
name = "Jailbird (0)"
cleanName = "Jailbird"
desc = "You have a criminal record and are currently on the run!"
id = "jailbird"
points = 0
isPositive = 0
/obj/trait/clericalerror
name = "Clerical Error (0)"
cleanName = "Clerical Error"
desc = "The name on your starting ID is misspelled."
id = "clericalerror"
icon_state = "spellingerror"
points = 0
isPositive = 1
/obj/trait/chemresist
name = "Chem resistant (-2)"
cleanName = "Chem resistant"
desc = "You are more resistant to chem overdoses."
id = "chemresist"
points = -2
isPositive = 1
/obj/trait/puritan
name = "Puritan (+2)"
cleanName = "Puritan"
desc = "You can not be cloned. Any attempt will end badly."
id = "puritan"
points = 2
isPositive = 0
/obj/trait/survivalist
name = "Survivalist (-1)"
cleanName = "Survivalist"
desc = "Food will heal you even if you are badly injured."
id = "survivalist"
points = -1
isPositive = 1
/obj/trait/smoker
name = "Smoker (-1)"
cleanName = "Smoker"
desc = "You will not absorb any chemicals from smoking cigarettes."
id = "smoker"
icon_state = "smoker"
points = -1
isPositive = 1
/obj/trait/immigrant
name = "Stowaway (+1)"
cleanName = "Stowaway"
desc = "You spawn hidden away on-station without an ID or PDA."
id = "immigrant"
points = 1
isPositive = 0
/obj/trait/nervous
name = "Nervous (+1)"
cleanName = "Nervous"
desc = "Witnessing injuries or violence will sometimes make you freak out."
id = "nervous"
icon_state = "nervous"
points = 1
isPositive = 0
onAdd(var/mob/owner)
..()
nervous_mobs += owner
onRemove(var/mob/owner)
..()
nervous_mobs -= owner
/obj/trait/burning
name = "Human Torch (+1)"
cleanName = "Human Torch"
desc = "Extends the time that you remain on fire for, when burning."
id = "burning"
icon_state = "onfire"
points = 1
isPositive = 0
/obj/trait/carpenter
name = "Carpenter (-1)"
cleanName = "Carpenter"
desc = "You can construct things more quickly than other people."
id = "carpenter"
points = -1
isPositive = 1
/obj/trait/kleptomaniac
name = "Kleptomaniac (+1)"
cleanName = "Kleptomaniac"
desc = "You will sometimes randomly pick up nearby items."
id = "kleptomaniac"
points = 1
isPositive = 0
onLife(var/mob/owner)
if(!owner.stat && can_act(owner) && prob(9))
if(!owner.equipped())
for(var/obj/item/I in view(1, owner))
if(!I.anchored && isturf(I.loc))
I.attack_hand(owner)
if(prob(12))
owner.emote(pick("grin", "smirk", "chuckle", "smug"))
break
return
/obj/trait/clutz
name = "Clutz (+2)"
cleanName = "Clutz"
desc = "When interacting with anything you have a chance to interact with something different instead."
id = "clutz"
points = 2
isPositive = 0
/obj/trait/leftfeet
name = "Two left feet (+1)"
cleanName = "Two left feet"
desc = "Every now and then you'll stumble in a random direction."
id = "leftfeet"
points = 1
isPositive = 0
/obj/trait/scaredshitless
name = "Scared Shitless (0)"
cleanName = "Scared Shitless"
desc = "Literally. When you scream, you fart. Be careful around Bibles!"
id = "scaredshitless"
icon_state = "poo"
points = 0
isPositive = 0
/obj/trait/allergic
name = "Hyperallergic (+1)"
cleanName = "Hyperallergic"
desc = "You have a severe sensitivity to allergens and are liable to slip into anaphylactic shock upon exposure."
id = "allergic"
icon_state = "placeholder"
points = 1
isPositive = 0
/obj/trait/bigbutt
name = "Dummy Thick (-2)"
desc = "Your buttocks are stubbornly chunky, and they clap together even when sneaking around."
id = "bigbutt"
icon_state = "bigbutt"
points = -2
isPositive = 0
isMoveTrait = 1
onMove(var/mob/owner)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.footstep >= 3)
playsound(H.loc, "sound/impact_sounds/Slap.ogg", 40, 1)
return