Merge pull request #4420 from Citadel-Station-13/upstream-merge-33405
[MIRROR] [Ready]Brain Trauma additions
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
/datum/brain_trauma/special/imaginary_friend
|
||||
name = "Imaginary Friend"
|
||||
desc = "Patient can see and hear an imaginary person."
|
||||
scan_desc = "partial schizophrenia"
|
||||
gain_text = "<span class='notice'>You feel in good company, for some reason.</span>"
|
||||
lose_text = "<span class='warning'>You feel lonely again.</span>"
|
||||
var/mob/camera/imaginary_friend/friend
|
||||
var/friend_initialized = FALSE
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_gain()
|
||||
..()
|
||||
make_friend()
|
||||
get_ghost()
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_life()
|
||||
if(get_dist(owner, friend) > 9)
|
||||
friend.yank()
|
||||
if(!friend)
|
||||
qdel(src)
|
||||
return
|
||||
if(!friend.client && friend_initialized)
|
||||
addtimer(CALLBACK(src, .proc/reroll_friend), 600)
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_lose()
|
||||
..()
|
||||
QDEL_NULL(friend)
|
||||
|
||||
//If the friend goes afk, make a brand new friend. Plenty of fish in the sea of imagination.
|
||||
/datum/brain_trauma/special/imaginary_friend/proc/reroll_friend()
|
||||
if(friend.client) //reconnected
|
||||
return
|
||||
friend_initialized = FALSE
|
||||
QDEL_NULL(friend)
|
||||
make_friend()
|
||||
get_ghost()
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/proc/make_friend()
|
||||
friend = new(get_turf(src), src)
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/proc/get_ghost()
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend)
|
||||
if(LAZYLEN(candidates))
|
||||
var/client/C = pick(candidates)
|
||||
friend.key = C.key
|
||||
friend_initialized = TRUE
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/mob/camera/imaginary_friend
|
||||
name = "imaginary friend"
|
||||
real_name = "imaginary friend"
|
||||
move_on_shuttle = TRUE
|
||||
desc = "A wonderful yet fake friend."
|
||||
see_in_dark = 0
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
||||
sight = NONE
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
var/icon/human_image
|
||||
var/image/current_image
|
||||
var/mob/living/carbon/owner
|
||||
var/datum/brain_trauma/special/imaginary_friend/trauma
|
||||
|
||||
/mob/camera/imaginary_friend/Login()
|
||||
..()
|
||||
to_chat(src, "<span class='notice'><b>You are the imaginary friend of [owner]!</b></span>")
|
||||
to_chat(src, "<span class='notice'>You are absolutely loyal to your friend, no matter what.</span>")
|
||||
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what [owner] cannot.</span>")
|
||||
|
||||
/mob/camera/imaginary_friend/Initialize(mapload, _trauma)
|
||||
. = ..()
|
||||
var/gender = pick(MALE, FEMALE)
|
||||
real_name = random_unique_name(gender)
|
||||
name = real_name
|
||||
trauma = _trauma
|
||||
owner = trauma.owner
|
||||
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/proc/Show()
|
||||
if(!client) //nobody home
|
||||
return
|
||||
|
||||
//Remove old image from owner and friend
|
||||
if(owner.client)
|
||||
owner.client.images.Remove(current_image)
|
||||
|
||||
client.images.Remove(current_image)
|
||||
|
||||
//Generate image from the static icon and the current dir
|
||||
current_image = image(human_image, src, , MOB_LAYER, dir=src.dir)
|
||||
current_image.override = TRUE
|
||||
current_image.name = name
|
||||
|
||||
//Add new image to owner and friend
|
||||
if(owner.client)
|
||||
owner.client.images |= current_image
|
||||
|
||||
client.images |= current_image
|
||||
|
||||
/mob/camera/imaginary_friend/Destroy()
|
||||
if(owner.client)
|
||||
owner.client.images.Remove(human_image)
|
||||
if(client)
|
||||
client.images.Remove(human_image)
|
||||
return ..()
|
||||
|
||||
/mob/camera/imaginary_friend/proc/yank()
|
||||
if(!client) //don't bother if the friend is braindead
|
||||
return
|
||||
forceMove(get_turf(owner))
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/say(message)
|
||||
if (!message)
|
||||
return
|
||||
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "You cannot send IC messages (muted).")
|
||||
return
|
||||
if (src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
return
|
||||
|
||||
friend_talk(message)
|
||||
|
||||
/mob/camera/imaginary_friend/proc/friend_talk(message)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGSAY)
|
||||
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[say_quote(message)]</span></span>"
|
||||
var/dead_rendered = "<span class='game say'><span class='name'>[name] (Imaginary friend of [owner])</span> <span class='message'>[say_quote(message)]</span></span>"
|
||||
|
||||
to_chat(owner, "[rendered]")
|
||||
to_chat(src, "[rendered]")
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, owner)
|
||||
to_chat(M, "[link] [dead_rendered]")
|
||||
|
||||
/mob/camera/imaginary_friend/emote(act,m_type=1,message = null)
|
||||
return
|
||||
|
||||
/mob/camera/imaginary_friend/forceMove(atom/destination)
|
||||
dir = get_dir(get_turf(src), destination)
|
||||
loc = destination
|
||||
if(get_dist(src, owner) > 9)
|
||||
yank()
|
||||
return
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/movement_delay()
|
||||
return 2
|
||||
@@ -107,6 +107,26 @@
|
||||
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/healthy
|
||||
name = "Anosognosia"
|
||||
desc = "Patient always feels healthy, regardless of their condition."
|
||||
scan_desc = "self-awareness deficit"
|
||||
gain_text = "<span class='notice'>You feel great!</span>"
|
||||
lose_text = "<span class='warning'>You no longer feel perfectly healthy.</span>"
|
||||
|
||||
/datum/brain_trauma/mild/healthy/on_gain()
|
||||
owner.set_screwyhud(SCREWYHUD_HEALTHY)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/healthy/on_life()
|
||||
owner.set_screwyhud(SCREWYHUD_HEALTHY) //just in case of hallucinations
|
||||
owner.adjustStaminaLoss(-5) //no pain, no fatigue
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/healthy/on_lose()
|
||||
owner.set_screwyhud(SCREWYHUD_NONE)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/muscle_weakness
|
||||
name = "Muscle Weakness"
|
||||
desc = "Patient experiences occasional bouts of muscle weakness."
|
||||
@@ -133,3 +153,62 @@
|
||||
to_chat(owner, "<span class='warning'>You feel a sudden weakness in your muscles!</span>")
|
||||
owner.adjustStaminaLoss(50)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/muscle_spasms
|
||||
name = "Muscle Spasms"
|
||||
desc = "Patient has occasional muscle spasms, causing them to move unintentionally."
|
||||
scan_desc = "nervous fits"
|
||||
gain_text = "<span class='warning'>Your muscles feel oddly faint.</span>"
|
||||
lose_text = "<span class='notice'>You feel in control of your muscles again.</span>"
|
||||
|
||||
/datum/brain_trauma/mild/muscle_spasms/on_life()
|
||||
if(prob(7))
|
||||
switch(rand(1,5))
|
||||
if(1)
|
||||
if(owner.canmove && !isspaceturf(owner.loc))
|
||||
to_chat(owner, "<span class='warning'>Your leg spasms!</span>")
|
||||
step(owner, pick(GLOB.cardinals))
|
||||
if(2)
|
||||
if(owner.incapacitated())
|
||||
return
|
||||
var/obj/item/I = owner.get_active_held_item()
|
||||
if(I)
|
||||
to_chat(owner, "<span class='warning'>Your fingers spasm!</span>")
|
||||
log_attack("[key_name(owner)] used [I] due to a Muscle Spasm.")
|
||||
I.attack_self(owner)
|
||||
if(3)
|
||||
var/prev_intent = owner.a_intent
|
||||
owner.a_intent = INTENT_HARM
|
||||
|
||||
var/range = 1
|
||||
if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at
|
||||
range = 7
|
||||
|
||||
var/list/mob/living/targets = list()
|
||||
for(var/mob/M in oview(owner, range))
|
||||
if(isliving(M))
|
||||
targets += M
|
||||
if(LAZYLEN(targets))
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] attacked someone due to a Muscle Spasm.") //the following attack will log itself
|
||||
owner.ClickOn(pick(targets))
|
||||
owner.a_intent = prev_intent
|
||||
if(4)
|
||||
var/prev_intent = owner.a_intent
|
||||
owner.a_intent = INTENT_HARM
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] attacked himself to a Muscle Spasm.")
|
||||
owner.ClickOn(owner)
|
||||
owner.a_intent = prev_intent
|
||||
if(5)
|
||||
if(owner.incapacitated())
|
||||
return
|
||||
var/obj/item/I = owner.get_active_held_item()
|
||||
var/list/turf/targets = list()
|
||||
for(var/turf/T in oview(owner, 3))
|
||||
targets += T
|
||||
if(LAZYLEN(targets) && I)
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.")
|
||||
owner.throw_item(pick(targets))
|
||||
..()
|
||||
@@ -7,7 +7,7 @@
|
||||
/datum/brain_trauma/severe/mute
|
||||
name = "Mutism"
|
||||
desc = "Patient is completely unable to speak."
|
||||
scan_desc = "extensive damage to the brain's language center"
|
||||
scan_desc = "extensive damage to the brain's speech center"
|
||||
gain_text = "<span class='warning'>You forget how to speak!</span>"
|
||||
lose_text = "<span class='notice'>You suddenly remember how to speak.</span>"
|
||||
|
||||
@@ -25,6 +25,29 @@
|
||||
owner.disabilities &= ~MUTE
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/aphasia
|
||||
name = "Aphasia"
|
||||
desc = "Patient is unable to speak or understand any language."
|
||||
scan_desc = "extensive damage to the brain's language center"
|
||||
gain_text = "<span class='warning'>You have trouble forming words in your head...</span>"
|
||||
lose_text = "<span class='notice'>You suddenly remember how languages work.</span>"
|
||||
var/datum/language_holder/prev_language
|
||||
var/datum/language_holder/mob_language
|
||||
|
||||
/datum/brain_trauma/severe/aphasia/on_gain()
|
||||
mob_language = owner.get_language_holder()
|
||||
prev_language = mob_language.copy()
|
||||
mob_language.remove_all_languages()
|
||||
mob_language.grant_language(/datum/language/aphasia)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/aphasia/on_lose()
|
||||
mob_language.remove_language(/datum/language/aphasia)
|
||||
mob_language.copy_known_languages_from(prev_language) //this will also preserve languages learned during the trauma
|
||||
QDEL_NULL(prev_language)
|
||||
mob_language = null
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/blindness
|
||||
name = "Cerebral Blindness"
|
||||
desc = "Patient's brain is no longer connected to its eyes."
|
||||
@@ -177,3 +200,18 @@
|
||||
/datum/brain_trauma/severe/discoordination/on_lose()
|
||||
owner.disabilities &= ~MONKEYLIKE
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/pacifism
|
||||
name = "Traumatic Non-Violence"
|
||||
desc = "Patient is extremely unwilling to harm others in violent ways."
|
||||
scan_desc = "pacific syndrome"
|
||||
gain_text = "<span class='notice'>You feel oddly peaceful.</span>"
|
||||
lose_text = "<span class='notice'>You no longer feel compelled to not harm.</span>"
|
||||
|
||||
/datum/brain_trauma/severe/pacifism/on_gain()
|
||||
owner.disabilities |= PACIFISM
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/pacifism/on_lose()
|
||||
owner.disabilities &= ~PACIFISM
|
||||
..()
|
||||
@@ -9,25 +9,35 @@
|
||||
scan_desc = "god delusion"
|
||||
gain_text = "<span class='notice'>You feel a higher power inside your mind...</span>"
|
||||
lose_text = "<span class='warning'>The divine presence leaves your head, no longer interested.</span>"
|
||||
var/next_speech = 0
|
||||
var/inspiration = FALSE
|
||||
|
||||
/datum/brain_trauma/special/godwoken/on_life()
|
||||
..()
|
||||
if(!inspiration && world.time > next_speech && prob(4))
|
||||
to_chat(owner, "<span class='notice'>[pick("You feel inspired!","You feel power course through you...","You feel something within you itching to speak...")]</span>")
|
||||
inspiration = TRUE
|
||||
if(prob(4))
|
||||
if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious()))
|
||||
speak("unstun", TRUE)
|
||||
else if(prob(60) && owner.health <= HEALTH_THRESHOLD_CRIT)
|
||||
speak("heal", TRUE)
|
||||
else if(prob(30) && owner.a_intent == INTENT_HARM)
|
||||
speak("aggressive")
|
||||
else
|
||||
speak("neutral", prob(25))
|
||||
|
||||
/datum/brain_trauma/special/godwoken/on_say(message)
|
||||
if(world.time > next_speech && inspiration)
|
||||
playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 300, 1, 5)
|
||||
var/cooldown = voice_of_god(message, owner, list("colossus","yell"), 2)
|
||||
cooldown *= 0.33
|
||||
next_speech = world.time + cooldown
|
||||
inspiration = FALSE
|
||||
return ""
|
||||
else
|
||||
return message
|
||||
/datum/brain_trauma/special/godwoken/proc/speak(type, include_owner = FALSE)
|
||||
var/message
|
||||
switch(type)
|
||||
if("unstun")
|
||||
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_unstun")
|
||||
if("heal")
|
||||
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_heal")
|
||||
if("neutral")
|
||||
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral")
|
||||
if("aggressive")
|
||||
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_aggressive")
|
||||
else
|
||||
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral")
|
||||
|
||||
playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 200, 1, 5)
|
||||
voice_of_god(message, owner, list("colossus","yell"), 2.5, include_owner, FALSE)
|
||||
|
||||
/datum/brain_trauma/special/bluespace_prophet
|
||||
name = "Bluespace Prophecy"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
/datum/brain_trauma/severe/split_personality/proc/get_ghost()
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", null, null, null, 75, stranger_backseat)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/client/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
@@ -136,6 +136,7 @@
|
||||
/mob/living/split_personality/Login()
|
||||
..()
|
||||
to_chat(src, "<span class='notice'>As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality.</span>")
|
||||
to_chat(src, "<span class='warning'><b>Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.</b></span>")
|
||||
|
||||
/mob/living/split_personality/say(message)
|
||||
to_chat(src, "<span class='warning'>You cannot speak, your other self is controlling your body!</span>")
|
||||
|
||||
@@ -44,11 +44,9 @@
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 40, 1, -1)
|
||||
D.apply_damage(rand(5,10), BRUTE, "head")
|
||||
A.apply_damage(rand(5,10), BRUTE, "head")
|
||||
if(!istype(A.head,/obj/item/clothing/head/helmet/) && !istype(A.head,/obj/item/clothing/head/hardhat))
|
||||
A.adjustBrainLoss(5)
|
||||
if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat))
|
||||
D.adjustBrainLoss(5)
|
||||
A.Stun(rand(5,30))
|
||||
A.Stun(rand(10,45))
|
||||
D.Stun(rand(5,30))
|
||||
if(5,6)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
|
||||
Reference in New Issue
Block a user