diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 6254f12e45..b5d07646d7 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -495,7 +495,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define RIDING_OFFSET_ALL "ALL"
//text files
-#define BRAIN_DAMAGE_FILE "brain_damage_lines.json"
+#define BRAIN_DAMAGE_FILE "traumas.json"
//Fullscreen overlay resolution in tiles.
#define FULLSCREEN_OVERLAY_RESOLUTION_X 15
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 49e3c996fe..707ef6a9c1 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -52,8 +52,8 @@
/*see __DEFINES/inventory.dm for bodypart bitflag defines*/
//Brain Damage defines
-#define BRAIN_DAMAGE_MILD 50
-#define BRAIN_DAMAGE_SEVERE 120
+#define BRAIN_DAMAGE_MILD 20
+#define BRAIN_DAMAGE_SEVERE 100
#define BRAIN_DAMAGE_DEATH 200
#define BRAIN_TRAUMA_MILD /datum/brain_trauma/mild
diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm
index 331bc6765f..a23f050c13 100644
--- a/code/__DEFINES/stat.dm
+++ b/code/__DEFINES/stat.dm
@@ -18,8 +18,9 @@
#define HUSK 64
#define NOCLONE 128
#define CLUMSY 256
-#define DUMB 512
-#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE
+#define DUMB 512
+#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE
+#define PACIFISM 2048
// bitflags for machine stat variable
#define BROKEN 1
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 727e149a97..2dddce8542 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -58,6 +58,8 @@
SendSignal(COMSIG_ITEM_ATTACK, M, user)
if(flags_1 & NOBLUDGEON_1)
return
+ if(user.disabilities & PACIFISM)
+ return
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
else if(hitsound)
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 02cdfe7c13..d52a7f6fdc 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -63,6 +63,7 @@
/atom/proc/attack_animal(mob/user)
return
+
/mob/living/RestrainedClickOn(atom/A)
return
diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm
new file mode 100644
index 0000000000..ea01a87506
--- /dev/null
+++ b/code/datums/brain_damage/imaginary_friend.dm
@@ -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 = "You feel in good company, for some reason."
+ lose_text = "You feel lonely again."
+ 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, "You are the imaginary friend of [owner]!")
+ to_chat(src, "You are absolutely loyal to your friend, no matter what.")
+ to_chat(src, "You cannot directly influence the world around you, but you can see what [owner] cannot.")
+
+/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 = "[name] [say_quote(message)]"
+ var/dead_rendered = "[name] (Imaginary friend of [owner]) [say_quote(message)]"
+
+ 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
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index 6bfa149aa7..7c2ba20a62 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -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 = "You feel great!"
+ lose_text = "You no longer feel perfectly healthy."
+
+/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, "You feel a sudden weakness in your muscles!")
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 = "Your muscles feel oddly faint."
+ lose_text = "You feel in control of your muscles again."
+
+/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, "Your leg spasms!")
+ 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, "Your fingers spasm!")
+ 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, "Your arm spasms!")
+ 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, "Your arm spasms!")
+ 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, "Your arm spasms!")
+ log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.")
+ owner.throw_item(pick(targets))
+ ..()
\ No newline at end of file
diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm
index 08cee65085..ceda917713 100644
--- a/code/datums/brain_damage/severe.dm
+++ b/code/datums/brain_damage/severe.dm
@@ -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 = "You forget how to speak!"
lose_text = "You suddenly remember how to speak."
@@ -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 = "You have trouble forming words in your head..."
+ lose_text = "You suddenly remember how languages work."
+ 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 = "You feel oddly peaceful."
+ lose_text = "You no longer feel compelled to not harm."
+
+/datum/brain_trauma/severe/pacifism/on_gain()
+ owner.disabilities |= PACIFISM
+ ..()
+
+/datum/brain_trauma/severe/pacifism/on_lose()
+ owner.disabilities &= ~PACIFISM
+ ..()
\ No newline at end of file
diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm
index ddb8f8e6e6..db0ca60801 100644
--- a/code/datums/brain_damage/special.dm
+++ b/code/datums/brain_damage/special.dm
@@ -9,25 +9,35 @@
scan_desc = "god delusion"
gain_text = "You feel a higher power inside your mind..."
lose_text = "The divine presence leaves your head, no longer interested."
- 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, "[pick("You feel inspired!","You feel power course through you...","You feel something within you itching to speak...")]")
- 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"
diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm
index c726b2ecb5..deed1c8406 100644
--- a/code/datums/brain_damage/split_personality.dm
+++ b/code/datums/brain_damage/split_personality.dm
@@ -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, "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.")
+ to_chat(src, "Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.")
/mob/living/split_personality/say(message)
to_chat(src, "You cannot speak, your other self is controlling your body!")
diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm
index 0d6a85359d..28f8e9502c 100644
--- a/code/datums/martial/psychotic_brawl.dm
+++ b/code/datums/martial/psychotic_brawl.dm
@@ -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)
diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm
index 7ca82c1236..f5b50542d0 100644
--- a/code/game/objects/items/implants/implant.dm
+++ b/code/game/objects/items/implants/implant.dm
@@ -14,6 +14,9 @@
/obj/item/implant/proc/trigger(emote, mob/living/carbon/source)
return
+/obj/item/implant/proc/on_death(emote, mob/living/carbon/source)
+ return
+
/obj/item/implant/proc/activate()
return
diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm
index 8b19bb9d96..0dc22c3d83 100644
--- a/code/game/objects/items/implants/implant_explosive.dm
+++ b/code/game/objects/items/implants/implant_explosive.dm
@@ -3,7 +3,7 @@
desc = "And boom goes the weasel."
icon_state = "explosive"
actions_types = list(/datum/action/item_action/explosive_implant)
- // Explosive implant action is always availible.
+ // Explosive implant action is always available.
var/weak = 2
var/medium = 0.8
var/heavy = 0.4
@@ -11,6 +11,9 @@
var/popup = FALSE // is the DOUWANNABLOWUP window open?
var/active = FALSE
+/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed)
+ activate("death")
+
/obj/item/implant/explosive/get_data()
var/dat = {"Implant Specifications:
Name: Robust Corp RX-78 Employee Management Implant
@@ -23,10 +26,6 @@
"}
return dat
-/obj/item/implant/explosive/trigger(emote, mob/source)
- if(emote == "deathgasp")
- activate("death")
-
/obj/item/implant/explosive/activate(cause)
if(!cause || !imp_in || active)
return 0
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 194edd77b1..92dc109bbc 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -80,6 +80,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
/obj/effect/hallucination
invisibility = INVISIBILITY_OBSERVER
+ anchored = TRUE
var/mob/living/carbon/target = null
/obj/effect/hallucination/simple
diff --git a/code/modules/language/aphasia.dm b/code/modules/language/aphasia.dm
new file mode 100644
index 0000000000..070a792ecd
--- /dev/null
+++ b/code/modules/language/aphasia.dm
@@ -0,0 +1,13 @@
+/datum/language/aphasia
+ name = "Gibbering"
+ desc = "It is theorized that any sufficiently brain-damaged person can speak this language."
+ speech_verb = "garbles"
+ ask_verb = "mumbles"
+ whisper_verb = "mutters"
+ exclaim_verb = "screams incoherently"
+ flags_1 = LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD
+ key = "i"
+ syllables = list("m","n","gh","h","l","s","r","a","e","i","o","u")
+ space_chance = 20
+ default_priority = 10
+ icon_state = "aphasia"
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index edb82e7ad4..819ed8072f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -157,6 +157,8 @@
if(!throwable_mob.buckled)
thrown_thing = throwable_mob
stop_pulling()
+ if(disabilities & PACIFISM)
+ to_chat(src, "You gently let go of [throwable_mob].")
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
@@ -168,6 +170,10 @@
thrown_thing = I
dropItemToGround(I)
+ if(disabilities & PACIFISM && I.throwforce)
+ to_chat(src, "You set [I] down gently on the ground.")
+ return
+
if(thrown_thing)
visible_message("[src] has thrown [thrown_thing].")
add_logs(src, thrown_thing, "has thrown")
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index a6efaaa967..9ba1dcc033 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -198,7 +198,7 @@
update_stamina()
/mob/living/carbon/getBrainLoss()
- . = BRAIN_DAMAGE_DEATH
+ . = 0
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
. = B.get_brain_damage()
@@ -207,6 +207,7 @@
/mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
if(status_flags & GODMODE)
return 0
+ var/prev_brainloss = getBrainLoss()
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(!B)
return
@@ -224,6 +225,13 @@
else
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
+ if(prev_brainloss < 40 && brainloss >= 40)
+ to_chat(src, "You feel lightheaded.")
+ else if(prev_brainloss < 120 && brainloss >= 120)
+ to_chat(src, "You feel less in control of your thoughts.")
+ else if(prev_brainloss < 180 && brainloss >= 180)
+ to_chat(src, "You can feel your mind flickering on and off...")
+
/mob/living/carbon/setBrainLoss(amount)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 8c97bc71a3..b8d9d510fd 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -43,31 +43,32 @@
msg += ""
var/temp = getBruteLoss()
- if(temp)
- if (temp < 25)
- msg += "[t_He] [t_has] minor bruising.\n"
- else if (temp < 50)
- msg += "[t_He] [t_has] moderate bruising!\n"
- else
- msg += "[t_He] [t_has] severe bruising!\n"
+ if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy
+ if(temp)
+ if (temp < 25)
+ msg += "[t_He] [t_has] minor bruising.\n"
+ else if (temp < 50)
+ msg += "[t_He] [t_has] moderate bruising!\n"
+ else
+ msg += "[t_He] [t_has] severe bruising!\n"
- temp = getFireLoss()
- if(temp)
- if (temp < 25)
- msg += "[t_He] [t_has] minor burns.\n"
- else if (temp < 50)
- msg += "[t_He] [t_has] moderate burns!\n"
- else
- msg += "[t_He] [t_has] severe burns!\n"
+ temp = getFireLoss()
+ if(temp)
+ if (temp < 25)
+ msg += "[t_He] [t_has] minor burns.\n"
+ else if (temp < 50)
+ msg += "[t_He] [t_has] moderate burns!\n"
+ else
+ msg += "[t_He] [t_has] severe burns!\n"
- temp = getCloneLoss()
- if(temp)
- if(temp < 25)
- msg += "[t_He] [t_is] slightly deformed.\n"
- else if (temp < 50)
- msg += "[t_He] [t_is] moderately deformed!\n"
- else
- msg += "[t_He] [t_is] severely deformed!\n"
+ temp = getCloneLoss()
+ if(temp)
+ if(temp < 25)
+ msg += "[t_He] [t_is] slightly deformed.\n"
+ else if (temp < 50)
+ msg += "[t_He] [t_is] moderately deformed!\n"
+ else
+ msg += "[t_He] [t_is] severely deformed!\n"
if(disabilities & DUMB)
msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n"
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 6ed9291b83..39caec803b 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -187,31 +187,32 @@
else if(l_limbs_missing >= 2 && r_limbs_missing >= 2)
msg += "[t_He] [p_do()]n't seem all there.\n"
- if(temp)
- if(temp < 25)
- msg += "[t_He] [t_has] minor bruising.\n"
- else if(temp < 50)
- msg += "[t_He] [t_has] moderate bruising!\n"
- else
- msg += "[t_He] [t_has] severe bruising!\n"
+ if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy
+ if(temp)
+ if(temp < 25)
+ msg += "[t_He] [t_has] minor bruising.\n"
+ else if(temp < 50)
+ msg += "[t_He] [t_has] moderate bruising!\n"
+ else
+ msg += "[t_He] [t_has] severe bruising!\n"
- temp = getFireLoss()
- if(temp)
- if(temp < 25)
- msg += "[t_He] [t_has] minor burns.\n"
- else if (temp < 50)
- msg += "[t_He] [t_has] moderate burns!\n"
- else
- msg += "[t_He] [t_has] severe burns!\n"
+ temp = getFireLoss()
+ if(temp)
+ if(temp < 25)
+ msg += "[t_He] [t_has] minor burns.\n"
+ else if (temp < 50)
+ msg += "[t_He] [t_has] moderate burns!\n"
+ else
+ msg += "[t_He] [t_has] severe burns!\n"
- temp = getCloneLoss()
- if(temp)
- if(temp < 25)
- msg += "[t_He] [t_has] minor cellular damage.\n"
- else if(temp < 50)
- msg += "[t_He] [t_has] moderate cellular damage!\n"
- else
- msg += "[t_He] [t_has] severe cellular damage!\n"
+ temp = getCloneLoss()
+ if(temp)
+ if(temp < 25)
+ msg += "[t_He] [t_has] minor cellular damage.\n"
+ else if(temp < 50)
+ msg += "[t_He] [t_has] moderate cellular damage!\n"
+ else
+ msg += "[t_He] [t_has] severe cellular damage!\n"
if(fire_stacks > 0)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index a3ebf5ab2f..866c14242f 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1315,11 +1315,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
+ if(user.disabilities & PACIFISM)
+ to_chat(user, "You don't want to harm [target]!")
+ return FALSE
if(target.check_block())
target.visible_message("[target] blocks [user]'s attack!")
- return 0
+ return FALSE
if(attacker_style && attacker_style.harm_act(user,target))
- return 1
+ return TRUE
else
var/atk_verb = user.dna.species.attack_verb
@@ -1344,7 +1347,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
playsound(target.loc, user.dna.species.miss_sound, 25, 1, -1)
target.visible_message("[user] has attempted to [atk_verb] [target]!",\
"[user] has attempted to [atk_verb] [target]!", null, COMBAT_MESSAGE_RANGE)
- return 0
+ return FALSE
var/armor_block = target.run_armor_check(affecting, "melee")
@@ -1511,8 +1514,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.confused = max(H.confused, 20)
H.adjustBrainLoss(20)
H.adjust_blurriness(10)
- if(prob(20))
+ if(prob(10))
H.gain_trauma(/datum/brain_trauma/mild/concussion)
+ else
+ if(!I.is_sharp())
+ H.adjustBrainLoss(I.force / 5)
if(prob(I.force + ((100 - H.health)/2)) && H != user)
var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev)
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index d6afdbdbc2..09d00465ee 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -120,16 +120,19 @@
/mob/living/carbon/monkey/proc/should_target(var/mob/living/L)
if(L == src)
- return 0
+ return FALSE
+
+ if(disabilities & PACIFISM)
+ return FALSE
if(enemies[L])
- return 1
+ return TRUE
// target non-monkey mobs when aggressive, with a small probability of monkey v monkey
if(aggressive && (!istype(L, /mob/living/carbon/monkey/) || prob(MONKEY_AGGRESSIVE_MVM_PROB)))
- return 1
+ return TRUE
- return 0
+ return FALSE
/mob/living/carbon/monkey/proc/handle_combat()
// Don't do any AI if inside another mob (devoured)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 0aafef753f..3ae022cdcc 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -137,6 +137,9 @@
eye_blurry = max(eye_blurry-1, 0)
if(client && !eye_blurry)
clear_fullscreen("blurry")
+ if(disabilities & PACIFISM && a_intent == INTENT_HARM)
+ to_chat(src, "You don't feel like harming anybody.")
+ a_intent_change(INTENT_HELP)
/mob/living/proc/update_damage_hud()
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index a5fac98d49..6ee1ed5229 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -809,9 +809,12 @@
to_chat(src, "You don't have the dexterity to do this!")
return
/mob/living/proc/can_use_guns(obj/item/G)
- if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser())
+ if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser())
to_chat(src, "You don't have the dexterity to do this!")
return FALSE
+ if(disabilities & PACIFISM)
+ to_chat(src, "You don't want to risk harming anyone!")
+ return FALSE
return TRUE
/mob/living/carbon/proc/update_stamina()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 8d4f29a0ee..ed07313862 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -127,14 +127,19 @@
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src || anchored || !isturf(user.loc))
- return 0
+ return FALSE
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
return
if(!(status_flags & CANPUSH))
to_chat(user, "[src] can't be grabbed more aggressively!")
- return 0
+ return FALSE
+
+ if(user.disabilities & PACIFISM)
+ to_chat(user, "You don't want to risk hurting [src]!")
+ return FALSE
+
grippedby(user)
//proc to upgrade a simple pull into a more aggressive grab.
@@ -188,83 +193,101 @@
M.Feedstop()
return // can't attack while eating!
+ if(disabilities & PACIFISM)
+ to_chat(M, "You don't want to hurt anyone!")
+ return FALSE
+
if (stat != DEAD)
add_logs(M, src, "attacked")
M.do_attack_animation(src)
visible_message("The [M.name] glomps [src]!", \
"The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE)
- return 1
+ return TRUE
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
if(M.melee_damage_upper == 0)
M.visible_message("\The [M] [M.friendly] [src]!")
- return 0
+ return FALSE
else
+ if(M.disabilities & PACIFISM)
+ to_chat(M, "You don't want to hurt anyone!")
+ return FALSE
+
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("\The [M] [M.attacktext] [src]!", \
"\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "attacked")
- return 1
+ return TRUE
/mob/living/attack_paw(mob/living/carbon/monkey/M)
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
- return 0
+ return FALSE
if (M.a_intent == INTENT_HARM)
+ if(M.disabilities & PACIFISM)
+ to_chat(M, "You don't want to hurt anyone!")
+ return FALSE
+
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "You can't bite with your mouth covered!")
- return 0
+ return FALSE
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
add_logs(M, src, "attacked")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("[M.name] bites [src]!", \
"[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
- return 1
+ return TRUE
else
visible_message("[M.name] has attempted to bite [src]!", \
"[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
- return 0
+ return FALSE
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if("help")
visible_message("[L.name] rubs its head against [src].")
- return 0
+ return FALSE
else
+ if(L.disabilities & PACIFISM)
+ to_chat(L, "You don't want to hurt anyone!")
+ return
+
L.do_attack_animation(src)
if(prob(90))
add_logs(L, src, "attacked")
visible_message("[L.name] bites [src]!", \
"[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- return 1
+ return TRUE
else
visible_message("[L.name] has attempted to bite [src]!", \
"[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
- return 0
+ return FALSE
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
switch(M.a_intent)
if ("help")
visible_message("[M] caresses [src] with its scythe like arm.")
- return 0
-
+ return FALSE
if ("grab")
grabbedby(M)
- return 0
+ return FALSE
if("harm")
+ if(M.disabilities & PACIFISM)
+ to_chat(M, "You don't want to hurt anyone!")
+ return FALSE
M.do_attack_animation(src)
- return 1
+ return TRUE
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
- return 1
+ return TRUE
/mob/living/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index a8d6e7840a..ba988f450d 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -15,7 +15,8 @@
/datum/language/monkey,
/datum/language/narsie,
/datum/language/beachbum,
- /datum/language/ratvar
+ /datum/language/ratvar,
+ /datum/language/aphasia
))
/obj/item/organ/tongue/Initialize(mapload)
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index 78f258be67..cc0324ab6a 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -119,7 +119,7 @@
///////////VOICE OF GOD///////////////
//////////////////////////////////////
-/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1)
+/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1, include_speaker = FALSE, message_admins = TRUE)
var/cooldown = 0
if(!user || !user.can_speak() || user.stat)
@@ -139,7 +139,9 @@
message = lowertext(message)
var/mob/living/list/listeners = list()
for(var/mob/living/L in get_hearers_in_view(8, user))
- if(L.can_hear() && !L.null_rod_check() && L != user && L.stat != DEAD)
+ if(L.can_hear() && !L.null_rod_check() && L.stat != DEAD)
+ if(L == user && !include_speaker)
+ continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
@@ -209,12 +211,12 @@
var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt")
var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown")
var/static/regex/sleep_words = regex("sleep|slumber|rest")
- var/static/regex/vomit_words = regex("vomit|throw up")
- var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush")
+ var/static/regex/vomit_words = regex("vomit|throw up|sick")
+ var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush")
var/static/regex/hallucinate_words = regex("see the truth|hallucinate")
var/static/regex/wakeup_words = regex("wake up|awaken")
- var/static/regex/heal_words = regex("live|heal|survive|mend|heroes never die")
- var/static/regex/hurt_words = regex("die|suffer|hurt|pain")
+ var/static/regex/heal_words = regex("live|heal|survive|mend|life|heroes never die")
+ var/static/regex/hurt_words = regex("die|suffer|hurt|pain|death")
var/static/regex/bleed_words = regex("bleed|there will be blood")
var/static/regex/burn_words = regex("burn|ignite")
var/static/regex/hot_words = regex("heat|hot|hell")
@@ -566,7 +568,8 @@
else
cooldown = COOLDOWN_NONE
- message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
+ if(message_admins)
+ message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
log_game("[key_name(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].")
SSblackbox.record_feedback("tally", "voice_of_god", 1, log_message)
diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi
index f4894c2b90..4e627f16c7 100644
Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ
diff --git a/strings/brain_damage_lines.json b/strings/traumas.json
similarity index 82%
rename from strings/brain_damage_lines.json
rename to strings/traumas.json
index 4a28998e2c..9b14a7b530 100644
--- a/strings/brain_damage_lines.json
+++ b/strings/traumas.json
@@ -186,33 +186,55 @@
"",
";",
".h"
- ],
-
- "roles": [
- "heds",
- "ceptin",
- "hop",
- "arrdee",
- "sek"
- ],
-
- "cargo": [
- "GUNS",
- "HATS",
- "PIZEH",
- "MEMES",
- "GLOWY CYSTAL"
-
- ],
-
- "s_roles": [
- "ert",
- "shadowlig",
- "ninja",
- "admen",
- "mantor",
- "bluh daymon",
- "wizzerd"
-
- ]
+ ],
+
+ "god_foe": [
+ "MORTALS",
+ "HERETICS",
+ "INSECTS",
+ "UNBELIEVERS",
+ "BLASPHEMERS",
+ "PARASITES",
+ "WEAKLINGS",
+ "PEASANTS"
+ ],
+
+ "god_aggressive": [
+ "BEGONE, @pick(god_foe)!",
+ "DIE, @pick(god_foe)!",
+ "BLEED, @pick(god_foe)!",
+ "BURN, @pick(god_foe)!",
+ "ALL WILL FALL BEFORE ME!",
+ "ENDLESS SUFFERING AWAITS YOU, @pick(god_foe).",
+ "DEATH TO @pick(god_foe)!"
+ ],
+
+ "god_neutral": [
+ "STOP",
+ "HALT.",
+ "BE SILENT.",
+ "QUIET",
+ "SEE THE TRUTH BEFORE YOU, MORTALS.",
+ "MORTALS, SAY YOUR NAME",
+ "BEGONE, MORTALS.",
+ "BE HEALED, MORTALS. I AM FEELING MERCIFUL.",
+ "DANCE FOR ME, LITTLE MORTALS.",
+ "YOU. STOP.",
+ "REST, MORTALS, TOMORROW IS A LONG DAY.",
+ "YOU MORTALS MAKE ME SICK.",
+ "HONK..."
+ ],
+
+ "god_unstun": [
+ "GET UP. I HAVE NO TIME TO LOSE.",
+ "GET UP, PRIEST.",
+ "GET UP."
+ ],
+
+ "god_heal": [
+ "YOU WILL LIVE TO SEE ANOTHER DAY.",
+ "YOU SHALL SURVIVE THIS, MY PRIEST.",
+ "BE HEALED, PRIEST.",
+ "YOUR LIFE IS IMPORTANT. KEEP IT."
+ ]
}
diff --git a/tgstation.dme b/tgstation.dme
index 7f9f4707e1..e7d7919ad7 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -334,6 +334,7 @@
#include "code\datums\antagonists\revolution.dm"
#include "code\datums\antagonists\wizard.dm"
#include "code\datums\brain_damage\brain_trauma.dm"
+#include "code\datums\brain_damage\imaginary_friend.dm"
#include "code\datums\brain_damage\mild.dm"
#include "code\datums\brain_damage\phobia.dm"
#include "code\datums\brain_damage\severe.dm"
@@ -1624,6 +1625,7 @@
#include "code\modules\jobs\job_types\security.dm"
#include "code\modules\jobs\job_types\silicon.dm"
#include "code\modules\jobs\map_changes\map_changes.dm"
+#include "code\modules\language\aphasia.dm"
#include "code\modules\language\beachbum.dm"
#include "code\modules\language\codespeak.dm"
#include "code\modules\language\common.dm"