mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-12 23:52:20 +01:00
970 lines
27 KiB
Plaintext
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
|