Adds a Trait system (#4048)

* Works on trait system, wip.

* Finalizes traits.
Fixes a few bugs with medical machines assuming a max health of 100.
This commit is contained in:
Neerti
2017-10-13 02:17:39 -04:00
committed by Anewbe
parent ef13c24d40
commit a8513844ec
23 changed files with 1102 additions and 15 deletions

View File

@@ -34,4 +34,12 @@
on_created_text = "<span class='warning'>Life suddenly feels more precious.</span>"
on_expired_text = "<span class='notice'>Death is cheap again.</span>"
flags = MODIFIER_GENETIC
// Prevents borging (specifically the MMI part), actual effect is on the MMI.
/datum/modifier/no_borg
name = "Cyboernetic Incompatability"
desc = "For whatever reason, your brain is incompatable with direct cybernetic interfaces, such as the MMI."
flags = MODIFIER_GENETIC

View File

@@ -37,6 +37,10 @@
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
var/bleeding_rate_percent // Adjusts amount of blood lost when bleeding.
var/accuracy // Positive numbers makes hitting things with guns easier, negatives make it harder. Each point makes it 15% easier or harder, just like evasion.
var/accuracy_dispersion // Positive numbers make gun firing cover a wider tile range, and therefore more inaccurate. Negatives help negate dispersion penalties.
var/metabolism_percent // Adjusts the mob's metabolic rate, which affects reagent processing. Won't affect mobs without reagent processing.
/datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder
@@ -136,4 +140,71 @@
for(var/datum/modifier/M in modifiers)
if(istype(M, modifier_type))
return TRUE
return FALSE
return FALSE
// This displays the actual 'numbers' that a modifier is doing. Should only be shown in OOC contexts.
// When adding new effects, be sure to update this as well.
/datum/modifier/proc/describe_modifier_effects()
var/list/effects = list()
if(!isnull(max_health_flat))
effects += "You [max_health_flat > 0 ? "gain" : "lose"] [abs(max_health_flat)] maximum health."
if(!isnull(max_health_percent))
effects += "You [max_health_percent > 1.0 ? "gain" : "lose"] [multipler_to_percentage(max_health_percent, TRUE)] maximum health."
if(!isnull(disable_duration_percent))
effects += "Disabling effects on you last [multipler_to_percentage(disable_duration_percent, TRUE)] [disable_duration_percent > 1.0 ? "longer" : "shorter"]"
if(!isnull(incoming_damage_percent))
effects += "You take [multipler_to_percentage(incoming_damage_percent, TRUE)] [incoming_damage_percent > 1.0 ? "more" : "less"] damage."
if(!isnull(incoming_brute_damage_percent))
effects += "You take [multipler_to_percentage(incoming_brute_damage_percent, TRUE)] [incoming_brute_damage_percent > 1.0 ? "more" : "less"] brute damage."
if(!isnull(incoming_fire_damage_percent))
effects += "You take [multipler_to_percentage(incoming_fire_damage_percent, TRUE)] [incoming_fire_damage_percent > 1.0 ? "more" : "less"] fire damage."
if(!isnull(incoming_tox_damage_percent))
effects += "You take [multipler_to_percentage(incoming_tox_damage_percent, TRUE)] [incoming_tox_damage_percent > 1.0 ? "more" : "less"] toxin damage."
if(!isnull(incoming_oxy_damage_percent))
effects += "You take [multipler_to_percentage(incoming_oxy_damage_percent, TRUE)] [incoming_oxy_damage_percent > 1.0 ? "more" : "less"] oxy damage."
if(!isnull(incoming_clone_damage_percent))
effects += "You take [multipler_to_percentage(incoming_clone_damage_percent, TRUE)] [incoming_clone_damage_percent > 1.0 ? "more" : "less"] clone damage."
if(!isnull(incoming_hal_damage_percent))
effects += "You take [multipler_to_percentage(incoming_hal_damage_percent, TRUE)] [incoming_hal_damage_percent > 1.0 ? "more" : "less"] agony damage."
if(!isnull(incoming_healing_percent))
effects += "Healing applied to you is [multipler_to_percentage(incoming_healing_percent, TRUE)] [incoming_healing_percent > 1.0 ? "stronger" : "weaker"]."
if(!isnull(outgoing_melee_damage_percent))
effects += "Damage you do with melee weapons and unarmed combat is [multipler_to_percentage(outgoing_melee_damage_percent, TRUE)] \
[outgoing_melee_damage_percent > 1.0 ? "higher" : "lower"]."
if(!isnull(slowdown))
effects += "[slowdown > 0 ? "lose" : "gain"] [slowdown] slowdown."
if(!isnull(haste))
effects += "You move at maximum speed, and cannot be slowed by any means."
if(!isnull(evasion))
effects += "You are [abs(evasion * 15)]% [evasion > 0 ? "harder" : "easier"] to hit with weapons."
if(!isnull(bleeding_rate_percent))
effects += "You bleed [multipler_to_percentage(bleeding_rate_percent, TRUE)] [bleeding_rate_percent > 1.0 ? "faster" : "slower"]."
if(!isnull(accuracy))
effects += "It is [abs(accuracy * 15)]% [accuracy > 0 ? "easier" : "harder"] for you to hit someone with a ranged weapon."
if(!isnull(accuracy_dispersion))
effects += "Projectiles you fire are [accuracy_dispersion > 0 ? "more" : "less"] likely to stray from your intended target."
if(!isnull(metabolism_percent))
effects += "Your metabolism is [metabolism_percent > 1.0 ? "faster" : "slower"], \
causing reagents in your body to process, and hunger to occur [multipler_to_percentage(metabolism_percent, TRUE)] [metabolism_percent > 1.0 ? "faster" : "slower"]."
return jointext(effects, "<br>")
// Helper to format multiplers (e.g. 1.4) to percentages (like '40%')
/proc/multipler_to_percentage(var/multi, var/abs = FALSE)
if(abs)
return "[abs( ((multi - 1) * 100) )]%"
return "[((multi - 1) * 100)]%"

View File

@@ -1,10 +1,55 @@
/datum/modifier/frail
name = "frail"
desc = "You are more delicate than the average person."
/datum/modifier/trait
flags = MODIFIER_GENETIC // We want traits to persist if the person gets cloned.
flags = MODIFIER_GENETIC
/datum/modifier/trait/flimsy
name = "flimsy"
desc = "You're more fragile than most, and have less of an ability to endure harm."
on_created_text = "<span class='warning'>You feel rather weak.</span>"
on_expired_text = "<span class='notice'>You feel your strength returning to you.</span>"
max_health_percent = 0.8
/datum/modifier/trait/frail
name = "frail"
desc = "Your body is very fragile, and has even less of an ability to endure harm."
on_created_text = "<span class='warning'>You feel really weak.</span>"
on_expired_text = "<span class='notice'>You feel your strength returning to you.</span>"
max_health_percent = 0.9
max_health_percent = 0.6
/datum/modifier/trait/weak
name = "weak"
desc = "A lack of physical strength causes a diminshed capability in close quarters combat"
outgoing_melee_damage_percent = 0.6
/datum/modifier/trait/haemophilia
name = "haemophilia"
desc = "You bleed much faster than average."
bleeding_rate_percent = 3.0
/datum/modifier/trait/inaccurate
name = "Inaccurate"
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
Regardless, you find it quite difficult to land shots where you wanted them to go."
accuracy = -1
accuracy_dispersion = 1
/datum/modifier/trait/high_metabolism
name = "High Metabolsim"
desc = "Your body's metabolism is faster than average."
metabolism_percent = 2.0
incoming_healing_percent = 1.4
/datum/modifier/trait/low_metabolism
name = "Low Metabolism"
desc = "Your body's metabolism is slower than average."
metabolism_percent = 0.5
incoming_healing_percent = 0.6

View File

@@ -0,0 +1,491 @@
// Gives various spooky messages to people afraid of a specific thing.
// Doesn't have any real mechanical effect, and is more of an aid to remind someone "You're supposed to be afraid of the dark", and such.
/datum/modifier/trait/phobia
var/current_fear = 0 // Counter for how 'afraid' the holder is.
var/max_fear = 100 // Cap for current_fear.
var/fear_decay_rate = 1 // How much is subtracted every Life() tick when not being spooked by something.
var/list/zero_fear_up = list() // Message displayed to holder when current_fear raises above 0.
var/list/zero_fear_down = list() // Message displayed when reaching 0.
var/list/half_fear_up = list() // Message displayed when current_fear passes half of max_fear.
var/list/half_fear_down = list() // Message displayed when current_fear goes below half of max_fear.
var/list/full_fear_up = list() // Similar to above, but for the cap.
var/list/full_fear_down = list() // Ditto.
/datum/modifier/trait/phobia/tick()
if(holder.stat)
return // You got bigger problems.
var/new_fear = should_fear()
if(new_fear)
adjust_fear(new_fear)
else
adjust_fear(-fear_decay_rate)
/datum/modifier/trait/phobia/proc/adjust_fear(var/amount)
var/last_fear = current_fear
current_fear = between(0, current_fear + amount, max_fear)
// Handle messages. safepick() is used so that if no messages are defined, it just does nothing, verses runtiming.
var/message = null
if(amount > 0) // Increase in spooks.
if(current_fear == max_fear && last_fear < max_fear)
message = safepick(full_fear_up)
else if(current_fear >= (max_fear / 2) && last_fear < (max_fear / 2))
message = safepick(half_fear_up)
else if(current_fear > 0 && last_fear == 0)
message = safepick(zero_fear_up)
else if(amount < 0) // Decrease in spooks.
if(last_fear == max_fear && current_fear < max_fear)
message = safepick(full_fear_down)
else if(last_fear >= (max_fear / 2) && current_fear < (max_fear / 2))
message = safepick(half_fear_down)
else if(last_fear > 0 && current_fear == 0)
message = safepick(zero_fear_down)
if(message)
to_chat(holder, message)
// Override for specific fears, e.g. seeing blood or spiders.
/datum/modifier/trait/phobia/proc/should_fear()
return FALSE
// Actual phobia trait implementations below.
/datum/modifier/trait/phobia/haemophobia
name = "haemophobia"
desc = "Seeing a bunch of blood isn't really pleasant for most people, but for you, it is very distressing."
fear_decay_rate = 4
on_created_text = "<span class='warning'>You are terrified of seeing blood.</span>"
on_expired_text = "<span class='notice'>You feel that blood doesn't bother you, at least, as much as it used to.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>You see some blood nearby...</font></span>",
"<span class='warning'><font size='3'>You try to avoid looking at the blood nearby.</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel better now, with no blood in sight.</span>",
"<span class='notice'>At last, the blood is gone.</span>",
"<span class='notice'>Hopefully you won't see anymore blood today.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>You're still near the blood!</font></span>",
"<span class='danger'><font size='3'>So much blood... You can't stand it.</font></span>"
)
half_fear_down = list(
"<span class='warning'>The blood is gone now, but you're still worked up.</span>",
"<span class='warning'>You can't see the blood now, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>The blood is too much!</font></span>",
"<span class='danger'><font size='4'>There is so much blood here, you need to leave!</font></span>",
"<span class='danger'><font size='4'>You gotta get away from the blood!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The blood is gone, but you're still very anxious.</span>",
"<span class='danger'>No more blood... Please.</span>"
)
/datum/modifier/trait/phobia/haemophobia/check_if_valid()
if(iscultist(holder)) // Nar-nar can't be having cultists afraid of blood.
expire()
else
..()
/datum/modifier/trait/phobia/haemophobia/should_fear()
if(holder.blinded)
return 0 // Can't fear what cannot be seen.
var/fear_amount = 0
for(var/atom/thing in view(5, holder)) // It's 5 and not 7 so players have a chance to go away before getting the prompts, and for performance.
// Blood stains are bad.
if(istype(thing, /obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = thing
// Tracks are special, apparently.
if(istype(thing, /obj/effect/decal/cleanable/blood/tracks))
var/obj/effect/decal/cleanable/blood/tracks/T = B
for(var/datum/fluidtrack/F in T.stack)
if(F.basecolor != SYNTH_BLOOD_COLOUR)
fear_amount++
break
else
if(B.basecolor != SYNTH_BLOOD_COLOUR)
fear_amount++
// People covered in blood is also bad.
// Feel free to trim down if its too expensive CPU wise.
if(istype(thing, /mob/living/carbon/human))
var/mob/living/carbon/human/H = thing
var/self_multiplier = H == holder ? 2 : 1
var/human_blood_fear_amount = 0
if(!H.gloves && H.bloody_hands && H.hand_blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
if(!H.shoes && H.feet_blood_color && H.feet_blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
// List of slots. Some slots like pockets are omitted due to not being visible, if H isn't the holder.
var/list/clothing_slots = list(H.back, H.wear_mask, H.l_hand, H.r_hand, H.wear_id, H.glasses, H.gloves, H.head, H.shoes, H.belt, H.wear_suit, H.w_uniform, H.s_store, H.l_ear, H.r_ear)
if(H == holder)
clothing_slots += list(H.l_store, H.r_store)
for(var/obj/item/clothing/C in clothing_slots)
if(C.blood_DNA && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
// This is divided, since humans can wear so many items at once.
human_blood_fear_amount = round( (human_blood_fear_amount * self_multiplier) / 3, 1)
fear_amount += human_blood_fear_amount
// Bloody objects are also bad.
if(istype(thing, /obj))
var/obj/O = thing
if(O.blood_DNA && O.blood_color && O.blood_color != SYNTH_BLOOD_COLOUR)
fear_amount++
return fear_amount
/datum/modifier/trait/phobia/arachnophobe
name = "arachnophobia"
desc = "Spiders are quite creepy to most people, however for you, those chitters of pure evil inspire pure dread and fear."
fear_decay_rate = 1
on_created_text = "<span class='warning'>You are terrified of seeing spiders.</span>"
on_expired_text = "<span class='notice'>You feel that your fear of spiders has gone from 'crippling' to 'nope nope nope', which is still an improvement.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>You see a spider!</font></span>",
"<span class='warning'><font size='3'>Spider!</font></span>"
)
zero_fear_down = list(
"<span class='notice'>Those evil spiders are finally gone.</span>",
"<span class='notice'>At last, the chitters are gone.</span>",
"<span class='notice'>The spiders are gone, at last.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>The spiders are gonna eat you!</font></span>",
"<span class='danger'><font size='3'>The spiders are still here!</font></span>",
"<span class='danger'><font size='3'>The spiders will lay eggs inside you if you don't run!</font></span>",
)
half_fear_down = list(
"<span class='warning'>The spiders are gone... right?</span>",
"<span class='warning'>You can't see any spiders now, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>The chittering is driving you mad!</font></span>",
"<span class='danger'><font size='4'>You're gonna be spider-food if you don't run!</font></span>",
"<span class='danger'><font size='4'>The spiders are gonna feast on your eyes!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The spiders must surely be hiding somewhere...</span>",
"<span class='danger'>No more spiders... Please.</span>"
)
/datum/modifier/trait/phobia/arachnophobe/should_fear()
if(holder.blinded)
return 0 // Can't fear what cannot be seen.
var/fear_amount = 0
for(var/atom/thing in view(5, holder)) // See haemophobia for why this is 5.
if(istype(thing, /obj/effect/decal/cleanable/spiderling_remains)) // Dead spiderlings are a bit spooky.
fear_amount += 1
if(istype(thing, /obj/effect/spider/spiderling)) // Live spiderlings are also spooky.
fear_amount += 2
if(istype(thing, /obj/item/toy/plushie/spider)) // Plushies are spooky so people can be assholes with them.
fear_amount += 1
if(istype(thing, /mob/living/simple_animal/hostile/giant_spider)) // Actual giant spiders are the scariest of them all.
var/mob/living/simple_animal/hostile/giant_spider/S = thing
if(S.stat == DEAD) // Dead giant spiders are less scary than alive ones.
fear_amount += 4
else
fear_amount += 8
return fear_amount
/datum/modifier/trait/phobia/nyctophobe
name = "nyctophobia"
desc = "More commonly known as the fear of darkness. The shadows can hide many dangers, which makes the prospect of going into the depths of Maintenance rather worrisome."
fear_decay_rate = 5
on_created_text = "<span class='warning'>You are terrified of the dark.</span>"
on_expired_text = "<span class='notice'>You feel that darkness isn't quite as scary anymore.</span>"
var/fear_threshold = 0.5 // Average lighting needs to be below this to start increasing fear.
zero_fear_up = list(
"<span class='warning'><font size='3'>It's so dark here!</font></span>",
"<span class='warning'><font size='3'>It's too dark!</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel calmer, now that you're in the light.</span>",
"<span class='notice'>At last, no more darkness.</span>",
"<span class='notice'>The light makes you feel calmer.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>You need to escape this darkness!</font></span>",
"<span class='danger'><font size='3'>Something might be lurking near you, but you can't see in this darkness.</font></span>",
"<span class='danger'><font size='3'>You need to find a light!</font></span>",
)
half_fear_down = list(
"<span class='warning'>The darkness is gone, for now...</span>",
"<span class='warning'>You're not in the dark anymore, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>What was that?</font></span>",
"<span class='danger'><font size='4'>Something is nearby...</font></span>"
)
full_fear_down = list(
"<span class='danger'>Light, at last!</span>",
"<span class='danger'>The darkness is finally gone!</span>"
)
/datum/modifier/trait/phobia/nyctophobe/should_fear()
if(holder.blinded)
return 5 // Unlike most other fears coded here, being blind when afraid of darkness is pretty bad, I imagine.
if(holder.see_in_dark >= 5)
return 0 // What darkness?
var/fear_amount = 0
var/total_lum = 0
var/total_tiles = 0
var/average_lum = null
for(var/turf/simulated/T in view(5, get_turf(holder))) // See haemophobia for why this is 5. This uses get_turf() since darkness makes tiles not visible to holder.
total_lum += T.get_lumcount()
total_tiles++
average_lum = total_lum / total_tiles
if(average_lum > fear_threshold)
switch(average_lum)
if(0.0 to 0.1)
fear_amount += 5
if(0.1 to 0.2)
fear_amount += 4
if(0.2 to 0.3)
fear_amount += 3
if(0.3 to 0.4)
fear_amount += 2
if(0.4 to 0.5)
fear_amount += 1
var/turf/T = get_turf(holder)
if(T.get_lumcount() <= LIGHTING_SOFT_THRESHOLD) // Standing in complete darkness.
fear_amount += 5
return fear_amount
/datum/modifier/trait/phobia/claustrophobe
name = "claustrophobia"
desc = "Small spaces and tight quarters makes you feel distressed. Unfortunately both are rather common when living in space."
fear_decay_rate = 2
var/open_tiles_needed = 15 // Tends to be just right, as maint triggers this but hallways don't.
on_created_text = "<span class='warning'>You are terrified of tight spaces. Why did you come to space??</span>"
on_expired_text = "<span class='notice'>Small rooms aren't so bad now.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>This room is too small...</font></span>",
"<span class='warning'><font size='3'>The walls are too close together...</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel calmer, now that you're in a larger room.</span>",
"<span class='notice'>At last, the walls are far apart.</span>",
"<span class='notice'>The relatively open area makes you feel calmer.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>Your surroundings look like they are closing in.</font></span>",
"<span class='danger'><font size='3'>Is the room getting smaller?</font></span>",
"<span class='danger'><font size='3'>You need to get out of here!</font></span>",
)
half_fear_down = list(
"<span class='warning'>Your surroundings seem to have stopped closing in.</span>",
"<span class='warning'>You're not in a tight space anymore, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>You need to escape!</font></span>",
"<span class='danger'><font size='4'>There's barely any room to move around!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The surroundings stop shrinking.</span>",
"<span class='danger'>The walls seem to have stopped.</span>"
)
/datum/modifier/trait/phobia/claustrophobe/should_fear()
if(holder.blinded)
return 0 // No idea if this is accurate.
if(holder.loc && !isturf(holder.loc)) // Hiding in a locker or inside an exosuit is spooky.
return 5
var/fear_amount = 0
var/open_tiles = 0
var/radius = 5 // See haemophobia for why this is 5.
var/max_open_tiles = radius * radius // Potential maximum tiles. In practice it will be rare for someone to be inside a 5x5 plane.
for(var/turf/T in view(radius, holder))
var/open = TRUE
if(T.density)
continue
for(var/atom/movable/AM in T)
if(AM.density)
open = FALSE
break
if(open)
open_tiles++
if(open_tiles < open_tiles_needed)
var/fear_reduction = abs( (open_tiles / max_open_tiles) - 1) // The smaller the space, the smaller this number is, and fear will build up faster.
fear_amount = 5 * fear_reduction
return fear_amount
// Note for the below 'phobias' are of the xeno-phobic variety, and are less centered on pure fear as above, and more on a mix of distrust, fear, and disdainfulness.
// As such, they are mechanically different than the fear-based phobias, in that instead of a buildup of fearful messages, it does intermittent messages specific to what holder sees.
// This is the catch-all 'everyone but [my species] is up to no good' trait, as opposed to the other specialized variants.
/datum/modifier/trait/phobia/xenophobia
name = "xenophobia"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
on_created_text = "<span class='warning'>You remain vigilant against the Alien.</span>"
on_expired_text = "<span class='notice'>Aliens aren't so bad afterall.</span>"
var/last_message = null // world.time we last did a message.
var/message_cooldown = 1 MINUTE
/datum/modifier/trait/phobia/xenophobia/tick()
if(holder.stat)
return // You got bigger problems.
if(last_message + message_cooldown <= world.time)
if(intermittent_message())
last_message = world.time
/datum/modifier/trait/phobia/xenophobia/proc/intermittent_message()
var/list/xenos = get_xenos()
if(xenos.len)
var/chosen_xeno = pick(xenos)
to_chat(holder, "<span class='warning'><font size='3'>[make_message(chosen_xeno)]</font></span>")
return TRUE
else
return FALSE // No xenos in sight, so don't apply the cooldown.
/datum/modifier/trait/phobia/xenophobia/proc/get_xenos()
return list()
/datum/modifier/trait/phobia/xenophobia/proc/make_message(var/mob/living/L)
return "Someone forgot to override this output message."
// This is the catch-all 'everyone but [my species] is up to no good' trait, as opposed to the other specialized variants.
/datum/modifier/trait/phobia/xenophobia/generic
name = "xenophobia"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
on_created_text = "<span class='warning'>You remain vigilant against the Alien.</span>"
on_expired_text = "<span class='notice'>Aliens aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/generic/get_xenos()
var/list/xenos = list()
if(!ishuman(holder))
return
var/mob/living/carbon/human/us = holder
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(!(istype(us.species, H.species) )) // Are they a different species?
xenos += H
return xenos
/datum/modifier/trait/phobia/xenophobia/generic/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// if(H.stat == DEAD)
// return pick( list("Unsurprising to see a weak and inferior [H.species.name] fail to survive.", "If that [H.species.name] were a [holder.species.name], this wouldn't've have happened.") )
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"That [H.species.name] is likely trying to spy on you.",
"[H.species.name_plural] tend to be ugly, but this one near you is even worse!",
"[H.species.name] scum.",
"The [H.species.name] nearby is certainly a spy for Them.",
"That [H.species.name] smells awful.",
"Can't trust [H.species.name_plural]."
)
return pick(generic_responses)
// *********
// * Human *
// *********
/datum/modifier/trait/phobia/xenophobia/human
name = "anti-human sentiment"
desc = "Humans are bound to get us all killed with their reckless use of technology..."
on_created_text = "<span class='warning'>You unfortunately are likely to have to deal with humans today.</span>"
on_expired_text = "<span class='notice'>Humans aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/human/get_xenos()
var/list/humans = list()
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(H == holder)
continue // No self loathing here.
if(istype(H.species, /datum/species/human) ) // Are they a human.
humans += H
return humans
/datum/modifier/trait/phobia/xenophobia/human/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"Why did you travel to human space? It's full of them."
)
return pick(generic_responses)
// **********
// * Skrell *
// **********
/datum/modifier/trait/phobia/xenophobia/skrell
name = "anti-skrell sentiment"
desc = "The Skrell pretend that they are Humanity's enlightened allies, but you can see past that."
on_created_text = "<span class='warning'>Hopefully no Skrell show up today.</span>"
on_expired_text = "<span class='notice'>Skrell aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/skrell/get_xenos()
var/list/skrell = list()
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(H == holder)
continue // No self loathing here.
if(istype(H.species, /datum/species/skrell) ) // Are they a squid now?
skrell += H
return skrell
/datum/modifier/trait/phobia/xenophobia/skrell/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"WetSkrell was a mistake."
)
return pick(generic_responses)