Files
2016-03-06 20:52:14 +01:00

790 lines
21 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.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()
for(var/X in traitList)
var/obj/trait/C = getTraitById(X)
if(C.unselectable) 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/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]
T.onAdd(owner)
return
proc/removeTrait(id)
if(traits.Find(id) && owner)
traits.Remove(id)
var/obj/trait/T = traitList[id]
T.onRemove(owner)
return
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/cleanName = "" //Name without any additional information.
proc/onAdd(var/mob/owner)
return
proc/onRemove(var/mob/owner)
return
proc/onLife(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
/obj/trait/alcoholic
name = "Career alcoholic (0)"
cleanName = "Career alcoholic"
desc = "You gain alcohol resistance but your speech is permanently slurred."
id = "alcoholic"
points = 0
isPositive = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("resist_alcohol")
return
/obj/trait/roboarms
name = "Robotic arms (0) \[Body\]"
cleanName = "Robotic arms"
desc = "Your arms have been replaced with light robotic arms."
id = "roboarms"
points = 0
isPositive = 1
category = "body"
onAdd(var/mob/owner)
spawn(40) //Fuck this. Fuck the way limbs are added with a delay. FUCK IT
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
if(H.limbs != null)
H.limbs.l_arm = new /obj/item/parts/robot_parts/arm/left/light(H)
H.limbs.r_arm = new /obj/item/parts/robot_parts/arm/right/light(H)
H.update_body()
return
/obj/trait/swedish
name = "Swedish (0) \[Language\]"
cleanName = "Swedish"
desc = "You are from sweden. Meat balls and so on."
id = "swedish"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_swedish")
return
/obj/trait/chav
name = "Chav (0) \[Language\]"
cleanName = "Chav"
desc = "U wot m8? I sware i'll fite u."
id = "chav"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_chav")
return
/obj/trait/tommy
name = "New Jersey Accent (0) \[Language\]"
cleanName = "New Jersey Accent"
desc = "Ha ha ha. What a story, Mark."
id = "tommy"
points = 0
isPositive = 1
category = "language"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_tommy")
return
/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", "tetrahydrocannabinol", "psilocybin", "cat drugs", "methamphetamine")
. = ..()
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
addAddiction(owner)
return
onLife(var/mob/owner) //Just to be safe.
if(istype(owner, /mob/living/carbon/human) && 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"
points = -1
isPositive = 1
/obj/trait/unionized
name = "Unionized (-1)"
cleanName = "Unionized"
desc = "You start with a higher paycheck than normal."
id = "unionized"
points = -1
isPositive = 1
/obj/trait/clericalerror
name = "Clerical Error (0)"
cleanName = "Clerical Error"
desc = "The name on your starting ID is misspelled."
id = "clericalerror"
points = 0
isPositive = 1
/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/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/smoothtalker
name = "Smooth talker (-1)"
cleanName = "Smooth talker"
desc = "Traders will tolerate 50% more when you are haggling with them."
id = "smoothtalker"
points = -1
isPositive = 1
/obj/trait/smoker
name = "Smoker (-1)"
cleanName = "Smoker"
desc = "You will not absorb any chemicals from smoking cigarettes."
id = "smoker"
points = -1
isPositive = 1
/obj/trait/immigrant
name = "Illegal immigrant (+1)"
cleanName = "Illegal immigrant"
desc = "You spawn without an ID or PDA."
id = "immigrant"
points = 1
isPositive = 0
/obj/trait/shortsighted
name = "Short-sighted (+1)"
cleanName = "Short-sighted"
desc = "Spawn with permanent short-sightedness and glasses."
id = "shortsighted"
points = 1
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("bad_eyesight")
H.equip_if_possible(new /obj/item/clothing/glasses/regular(H), H.slot_glasses)
return
onLife(var/mob/owner) //Just to be safe.
if(owner.bioHolder && !owner.bioHolder.HasEffect("bad_eyesight"))
owner.bioHolder.AddEffect("bad_eyesight")
return
/obj/trait/deaf
name = "Deaf (+1)"
cleanName = "Deaf"
desc = "Spawn with permanent deafness and an auditory headset."
id = "deaf"
points = 1
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("deaf")
H.equip_if_possible(new /obj/item/device/radio/headset/deaf(H), H.slot_ears)
return
onLife(var/mob/owner) //Just to be safe.
if(owner.bioHolder && !owner.bioHolder.HasEffect("deaf"))
owner.bioHolder.AddEffect("deaf")
return
/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/nervous
name = "Nervous (+1)"
cleanName = "Nervous"
desc = "Witnessing injuries or violence will sometimes make you freak out."
id = "nervous"
points = 1
isPositive = 0
/obj/trait/burning
name = "Human Torch (+1)"
cleanName = "Human Torch"
desc = "Extends the time that you remain on fire for, when burning."
id = "burning"
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/explolimbs
name = "Adamantium Skeleton (-2)"
cleanName = "Adamantium Skeleton"
desc = "Halves the chance that an explosion will blow off your limbs."
id = "explolimbs"
points = -2
isPositive = 1
/obj/trait/cateyes
name = "Cat eyes (-1) \[Vision\]"
cleanName = "Cat eyes"
desc = "You can see 2 tiles further in the dark."
id = "cateyes"
points = -1
isPositive = 1
category = "vision"
/obj/trait/infravision
name = "Infravision (-1) \[Vision\]"
cleanName = "Infravision"
desc = "You gain permanent infravision."
id = "infravision"
points = -1
isPositive = 0
category = "vision"
/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/spacephobia
name = "Spacephobia (+2)"
cleanName = "Spacephobia"
desc = "Being in space scares you. A lot. While in space you might panic or faint."
id = "spacephobia"
points = 2
isPositive = 0
onLife(var/mob/owner)
if(!owner.stat && can_act(owner) && istype(owner.loc, /turf/space))
if(prob(2))
owner.emote("faint")
owner.paralysis += 7
else if (prob(8))
owner.emote("scream")
owner.stunned += 2
return
/obj/trait/robustgenetics
name = "Robust Genetics (-2) \[Genetics\]"
cleanName = "Robust Genetics"
desc = "You gain an additional 20 genetic stability."
id = "robustgenetics"
points = -2
isPositive = 0
category = "genetics"
/obj/trait/stablegenes
name = "Stable Genes (-2) \[Genetics\]"
cleanName = "Stable Genes"
desc = "You are less likely to mutate from radiation or mutagens."
id = "stablegenes"
points = -2
isPositive = 0
category = "genetics"
/obj/trait/loyalist
name = "NT loyalist (-1) \[Trinkets\]"
cleanName = "NT loyalist"
desc = "Start with a Nanotrasen Beret as your trinket."
id = "loyalist"
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"
points = -1
isPositive = 1
category = "trinkets"
/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/lizard
name = "Lizard (-1) \[Race\]"
desc = "You spawn as a lizard. Remember; you have no rights as a human if you choose this trait!"
cleanName = "Lizard"
id = "lizard"
points = -1
isPositive = 1
category = "race"
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.set_mutantrace(/datum/mutantrace/lizard)
return
*/
//UNSELECTABLE BELOW////UNSELECTABLE BELOW////UNSELECTABLE BELOW////UNSELECTABLE BELOW////UNSELECTABLE BELOW////UNSELECTABLE BELOW////UNSELECTABLE BELOW//
// People use this to identify changelings and people wearing disguises and I can't be bothered
// to rewrite a whole bunch of stuff for what is essentially something very specific and minor.
/obj/trait/observant
name = "Observant (-1)"
cleanName = "Observant"
desc = "Examining people will show you their traits."
id = "observant"
points = -1
isPositive = 1
unselectable = 1
/obj/trait/roboears
name = "Robotic ears (-4) \[Body\]"
cleanName = "Robotic ears"
desc = "You can hear, understand and speak robotic languages."
id = "roboears"
category = "body"
points = -4
isPositive = 1
unselectable = 1
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.robot_talk_understand = 1
return
onLife(var/mob/owner) //Just to be safe.
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.robot_talk_understand = 1
return
/*
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
if(H.organHolder != null)
H.organHolder.receive_organ(var/obj/item/I, var/type, var/op_stage = 0.0)
return
*/
/obj/trait/deathwish
name = "Death wish (+8) \[Stats\]"
cleanName = "Death wish"
desc = "You take double damage from most things and have half your normal health."
id = "deathwish"
category = "stats"
points = 8
isPositive = 0
unselectable = 1
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.max_health = 50
H.health = 50
return
onLife(var/mob/owner) //Just to be safe.
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.max_health = 50
return
/obj/trait/glasscannon
name = "Glass cannon (-1) \[Stats\]"
cleanName = "Glass cannon"
desc = "You have 1 stamina max. Attacks no longer cost you stamina and\nyou deal double the normal damage with most melee weapons."
id = "glasscannon"
category = "stats"
points = -1
isPositive = 1
unselectable = 1
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.add_stam_mod_max("trait", -(STAMINA_MAX - 1))
return
/obj/trait/fat
name = "Fat (-1)"
cleanName = "Fat"
desc = "You're a little ... pudgy. And there's nothing you can do about it."
id = "fat"
points = -1
isPositive = 1
unselectable = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("fat")
return
onLife(var/mob/owner) //Just to be safe.
if(owner.bioHolder && !owner.bioHolder.HasEffect("fat"))
owner.bioHolder.AddEffect("fat")
return
/obj/trait/soggy
name = "Overly soggy (-1)"
cleanName = "Overly soggy"
desc = "When you die you explode into gibs and drop everything you were carrying."
id = "soggy"
points = -1
isPositive = 1
unselectable = 1
/obj/trait/badgenes
name = "Bad Genes (+2) \[Genetics\]"
cleanName = "Bad Genes"
desc = "You spawn with 2 random, permanent, bad mutations."
id = "badgenes"
points = 2
isPositive = 0
category = "genetics"
unselectable = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
var/str = "I have the following bad mutations: "
var/curr_id = owner.bioHolder.RandomEffect("bad", 1)
var/datum/bioEffect/curr = owner.bioHolder.effects[curr_id]
curr.curable_by_mutadone = 0
curr.can_reclaim = 0
curr.can_scramble = 0
str += " [curr.name],"
curr_id = owner.bioHolder.RandomEffect("bad", 1)
curr = owner.bioHolder.effects[curr_id]
curr.curable_by_mutadone = 0
curr.can_reclaim = 0
curr.can_scramble = 0
str += " [curr.name]"
spawn(40) owner.add_memory(str) //FUCK THIS SPAWN FUCK FUUUCK
return
/obj/trait/goodgenes
name = "Good Genes (-3) \[Genetics\]"
cleanName = "Good Genes"
desc = "You spawn with 2 random good mutations."
id = "goodgenes"
points = -3
isPositive = 0
category = "genetics"
unselectable = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
var/str = "I have the following good mutations: "
var/curr_id = owner.bioHolder.RandomEffect("good", 1)
var/datum/bioEffect/curr = owner.bioHolder.effects[curr_id]
str += " [curr.name],"
curr_id = owner.bioHolder.RandomEffect("good", 1)
curr = owner.bioHolder.effects[curr_id]
str += " [curr.name]"
spawn(40) owner.add_memory(str) //FUCK THIS SPAWN FUCK FUUUCK
return
//RANDOM SNIPPETS AND RUBBISH BELOW
/*
/obj/trait/testTrait1//
name = "Lizard (-1) \[Race\]"
desc = "You spawn as a lizard person thing. Yep.\nThere you go. Finally you can live out your dream."
id = "lizard"
points = -1
isPositive = 1
category = "race"
onAdd(var/mob/owner)
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.set_mutantrace(/datum/mutantrace/lizard)
return
/obj/trait/testTrait2
name = "Cough (+1) \[Race\]"
desc = "You suffer from a chronic cough."
id = "cough"
points = 1
isPositive = 0
category = "race"
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("cough")
return
/obj/trait/testTrait3
name = "Swedish (-1)"
desc = "You are from sweden. Meat balls and so on."
id = "swedish"//
points = -1
isPositive = 1
onAdd(var/mob/owner)
if(owner.bioHolder)
owner.bioHolder.AddEffect("accent_swedish")
return
*/
/*
var/mob/living/carbon/human/target = null
for(var/mob/living/carbon/human/M in range(1, owner))
if(M == owner || !istype(M,/mob/living/carbon/human)) continue
target = M
break
if(target)
if(!actions.hasAction(owner, "otheritem") && !owner.equipped())
var/trgSlot = null
if(target.get_slot(target.slot_l_hand)) trgSlot = target.slot_l_hand
else if(target.get_slot(target.slot_r_hand)) trgSlot = target.slot_r_hand
else if(target.get_slot(target.slot_wear_id)) trgSlot = target.slot_wear_id
else if(target.get_slot(target.slot_l_store)) trgSlot = target.slot_l_store
else if(target.get_slot(target.slot_r_store)) trgSlot = target.slot_r_store
else if(target.get_slot(target.slot_head)) trgSlot = target.slot_head
else if(target.get_slot(target.slot_back)) trgSlot = target.slot_back
else if(target.get_slot(target.slot_w_uniform)) trgSlot = target.slot_w_uniform
if(trgSlot)
actions.start(new/datum/action/bar/icon/otherItem( owner, target, null, trgSlot ) , owner)
*/