diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index a20efc98a06..0090dd654fd 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -3,15 +3,18 @@
//PUBLIC - call these wherever you want
-/mob/proc/throw_alert(category, type, severity, obj/new_master)
+/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE)
-/* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
+/*
+ Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
category is a text string. Each mob may only have one alert per category; the previous one will be replaced
path is a type path of the actual alert type to throw
severity is an optional number that will be placed at the end of the icon_state for this alert
For example, high pressure's icon_state is "highpressure" and can be serverity 1 or 2 to get "highpressure1" or "highpressure2"
new_master is optional and sets the alert's icon state to "template" in the ui_style icons with the master as an overlay.
- Clicks are forwarded to master */
+ Clicks are forwarded to master
+ Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations.
+ */
if(!category)
return
@@ -19,6 +22,8 @@
var/obj/screen/alert/alert
if(alerts[category])
alert = alerts[category]
+ if(alert.override_alerts)
+ return 0
if(new_master && new_master != alert.master)
WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [alert.master]")
clear_alert(category)
@@ -33,7 +38,10 @@
else //no need to update
return 0
else
- alert = new type
+ alert = new type()
+ alert.override_alerts = override
+ if(override)
+ alert.timeout = null
if(new_master)
var/old_layer = new_master.layer
@@ -63,10 +71,12 @@
return alert
// Proc to clear an existing alert.
-/mob/proc/clear_alert(category)
+/mob/proc/clear_alert(category, clear_override = FALSE)
var/obj/screen/alert/alert = alerts[category]
if(!alert)
return 0
+ if(alert.override_alerts && !clear_override)
+ return 0
alerts -= category
if(client && hud_used)
@@ -83,6 +93,7 @@
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
var/severity = 0
var/alerttooltipstyle = ""
+ var/override_alerts = FALSE //If it is overriding other alerts of the same type
/obj/screen/alert/MouseEntered(location,control,params)
@@ -197,12 +208,12 @@ The box in your backpack has an oxygen tank and gas mask in it."
name = "High Pressure"
desc = "The air around you is hazardously thick. A fire suit would protect you."
icon_state = "highpressure"
-
+
/obj/screen/alert/lightexposure
name = "Light Exposure"
desc = "You're exposed to light."
icon_state = "lightexposure"
-
+
/obj/screen/alert/nolight
name = "No Light"
desc = "You're not exposed to any light."
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 4c120db79e0..7ec0e700a3f 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -11,54 +11,57 @@ Gunshots/explosions/opening doors/less rare audio (done)
*/
-/mob/living/carbon/
+#define SCREWYHUD_NONE 0
+#define SCREWYHUD_CRIT 1
+#define SCREWYHUD_DEAD 2
+#define SCREWYHUD_HEALTHY 3
+
+/mob/living/carbon
var/image/halimage
var/image/halbody
var/obj/halitem
- var/hal_screwyhud = 0 //1 - critical, 2 - dead, 3 - oxygen indicator, 4 - toxin indicator
+ var/hal_screwyhud = SCREWYHUD_NONE
var/handling_hal = 0
- var/hal_crit = 0
/mob/living/carbon/proc/handle_hallucinations()
if(handling_hal)
return
//Least obvious
- var/list/minor = list("sounds"=20,"bolts_minor"=10,"whispers"=15,"message"=5)
+ var/list/minor = list("sounds"=25,"bolts_minor"=5,"whispers"=15,"message"=10,"hudscrew"=15)
//Something's wrong here
- var/list/medium = list("hudscrew"=15,"items"=15,"dangerflash"=15,"bolts"=10,"flood"=10,"husks"=10,"battle"=10)
- //AAAAH
- var/list/major = list("fake"=10,"death"=5,"xeno"=10,"singulo"=10,"delusion"=10)
-
- var/grade = 0
- var/current = list()
- var/trip_length = 0
+ var/list/medium = list("fake_alert"=15,"items"=10,"items_other"=10,"dangerflash"=10,"bolts"=5,"flood"=5,"husks"=10,"battle"=15,"self_delusion"=10)
+ //AAAAHg
+ var/list/major = list("fake"=20,"death"=10,"xeno"=10,"singulo"=10,"borer"=10,"delusion"=20,"koolaid"=10)
handling_hal = 1
while(hallucination > 20)
- sleep(rand(200,500)/(hallucination/25))
- trip_length += 1
- if(prob(min(20,trip_length*2)))
- grade = min(3,grade+1)
+ sleep(rand(200, 500) / (hallucination / 25))
if(prob(20))
continue
- current = list()
- for(var/a in minor)
- current[a] = minor[a] * (grade==0?2:1)
- for(var/b in medium)
- current[b] = medium[b] * (grade==1?2:1)
- for(var/c in major)
- current[c] = major[c] * (grade==2?2:1)
+ var/list/current = list()
+ switch(rand(100))
+ if(1 to 50)
+ current = minor
+ if(51 to 85)
+ current = medium
+ if(86 to 100)
+ current = major
var/halpick = pickweight(current)
hallucinate(halpick)
handling_hal = 0
+
/obj/effect/hallucination
invisibility = INVISIBILITY_OBSERVER
var/mob/living/carbon/target = null
+/obj/effect/hallucination/proc/wake_and_restore()
+ target.hal_screwyhud = SCREWYHUD_NONE
+ target.SetSleeping(0)
+
/obj/effect/hallucination/simple
var/image_icon = 'icons/mob/alien.dmi'
var/image_state = "alienh_pounce"
@@ -69,28 +72,31 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/image_layer = MOB_LAYER
var/active = 1 //qdelery
-/obj/effect/hallucination/simple/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/simple/New(loc, mob/living/carbon/T)
+ ..()
target = T
current_image = GetImage()
- if(target.client) target.client.images |= current_image
- return
+ if(target.client)
+ target.client.images |= current_image
/obj/effect/hallucination/simple/proc/GetImage()
- var/image/I = image(image_icon,loc,image_state,image_layer,dir=src.dir)
+ var/image/I = image(image_icon, src, image_state, image_layer, dir = dir)
I.pixel_x = px
I.pixel_y = py
if(col_mod)
I.color = col_mod
return I
-/obj/effect/hallucination/simple/proc/Show(var/update=1)
+/obj/effect/hallucination/simple/proc/Show(update = 1)
if(active)
- if(target.client) target.client.images.Remove(current_image)
+ if(target.client)
+ target.client.images.Remove(current_image)
if(update)
current_image = GetImage()
- if(target.client) target.client.images |= current_image
+ if(target.client)
+ target.client.images |= current_image
-/obj/effect/hallucination/simple/update_icon(var/new_state,var/new_icon,var/new_px=0,var/new_py=0)
+/obj/effect/hallucination/simple/update_icon(new_state, new_icon, new_px = 0, new_py = 0)
image_state = new_state
if(new_icon)
image_icon = new_icon
@@ -105,7 +111,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
Show()
/obj/effect/hallucination/simple/Destroy()
- if(target.client) target.client.images.Remove(current_image)
+ if(target.client)
+ target.client.images.Remove(current_image)
active = 0
return ..()
@@ -121,7 +128,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/radius = 0
var/next_expand = 0
-/obj/effect/hallucination/fake_flood/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/fake_flood/New(loc, mob/living/carbon/T)
..()
target = T
for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target))
@@ -131,7 +138,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
image_state = pick("plasma","sleeping_agent")
flood_images += image(image_icon,src,image_state,MOB_LAYER)
flood_turfs += get_turf(src.loc)
- if(target.client) target.client.images |= flood_images
+ if(target.client)
+ target.client.images |= flood_images
next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
processing_objects += src
@@ -142,24 +150,24 @@ Gunshots/explosions/opening doors/less rare audio (done)
qdel(src)
Expand()
next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
- return
/obj/effect/hallucination/fake_flood/proc/Expand()
if(!flood_turfs) //for qdel
return
- for(var/turf/T in circlerangeturfs(loc,radius))
- if((T in flood_turfs)|| T.blocks_air)
+ for(var/turf/T in circlerangeturfs(loc, radius))
+ if(T in flood_turfs || T.blocks_air)
continue
flood_images += image(image_icon,T,image_state,MOB_LAYER)
flood_turfs += T
- if(target.client) target.client.images |= flood_images
- return
+ if(target.client)
+ target.client.images |= flood_images
/obj/effect/hallucination/fake_flood/Destroy()
processing_objects -= src
- qdel(flood_turfs)
- if(target.client) target.client.images.Remove(flood_images)
+ if(target.client)
+ target.client.images.Remove(flood_images)
target = null
+ qdel(flood_turfs)
qdel(flood_images)
return ..()
@@ -170,15 +178,15 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/hallucination/simple/xeno/New(loc,var/mob/living/carbon/T)
..()
name = "alien hunter ([rand(1, 1000)])"
- return
/obj/effect/hallucination/simple/xeno/throw_at(atom/target, range, speed) // TODO : Make diagonal trhow into proc/property
- if(!target || !src || (flags & NODROP)) return 0
+ if(!target || !src || (flags & NODROP))
+ return 0
- src.throwing = 1
+ throwing = 1
- var/dist_x = abs(target.x - src.x)
- var/dist_y = abs(target.y - src.y)
+ var/dist_x = abs(target.x - x)
+ var/dist_y = abs(target.y - y)
var/dist_travelled = 0
var/dist_since_sleep = 0
@@ -190,15 +198,16 @@ Gunshots/explosions/opening doors/less rare audio (done)
tdist_y = dist_x;
var/error = tdist_x/2 - tdist_y
- while(target && (((((dist_x > dist_y) && ((src.x < target.x) || (src.x > target.x))) || ((dist_x <= dist_y) && ((src.y < target.y) || (src.y > target.y))) || (src.x > target.x)) && dist_travelled < range) || !has_gravity(src)))
+ while(target && (((((dist_x > dist_y) && ((x < target.x) || (x > target.x))) || ((dist_x <= dist_y) && ((y < target.y) || (y > target.y))) || (x > target.x)) && dist_travelled < range) || !has_gravity(src)))
+ if(!throwing)
+ break
+ if(!istype(loc, /turf))
+ break
- if(!src.throwing) break
- if(!istype(src.loc, /turf)) break
-
- var/atom/step = get_step(src, get_dir(src,target))
+ var/atom/step = get_step(src, get_dir(src, target))
if(!step)
break
- src.Move(step, get_dir(src, step))
+ Move(step, get_dir(src, step))
hit_check()
error += (error < 0) ? tdist_x : -tdist_y;
dist_travelled++
@@ -208,8 +217,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
sleep(1)
- src.throwing = 0
- src.throw_impact(get_turf(src))
+ throwing = 0
+ throw_impact(get_turf(src))
return 1
@@ -224,49 +233,155 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/obj/machinery/atmospherics/unary/vent_pump/pump = null
var/obj/effect/hallucination/simple/xeno/xeno = null
-/obj/effect/hallucination/xeno_attack/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/xeno_attack/New(loc, mob/living/carbon/T)
target = T
for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target))
if(!U.welded)
pump = U
break
- if(!pump) return 0
+ if(!pump)
+ return 0
xeno = new(pump.loc,target)
sleep(10)
- if(!xeno) return
+ if(!xeno)
+ return
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
xeno.throw_at(target,7,1)
sleep(10)
- if(!xeno) return
+ if(!xeno)
+ return
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
xeno.throw_at(pump,7,1)
sleep(10)
- if(!xeno) return
+ if(!xeno)
+ return
var/xeno_name = xeno.name
to_chat(target, "[xeno_name] begins climbing into the ventilation system...")
sleep(10)
- if(!xeno) return
+ if(!xeno)
+ return
qdel(xeno)
to_chat(target, "[xeno_name] scrambles into the ventilation ducts!")
qdel(src)
+/obj/effect/hallucination/simple/clown
+ image_icon = 'icons/mob/animal.dmi'
+ image_state = "clown"
+
+/obj/effect/hallucination/simple/clown/New(loc, mob/living/carbon/T, duration)
+ ..(loc, T)
+ name = pick(clown_names)
+ sleep(duration)
+ qdel(src)
+
+/obj/effect/hallucination/simple/clown/scary
+ image_state = "scary_clown"
+
+/obj/effect/hallucination/simple/borer
+ image_icon = 'icons/mob/animal.dmi'
+ image_state = "brainslug"
+
+/obj/effect/hallucination/borer
+ //A borer paralyzes you and crawls in your ear
+ var/obj/machinery/atmospherics/unary/vent_pump/pump = null
+ var/obj/effect/hallucination/simple/borer/borer = null
+
+/obj/effect/hallucination/borer/New(loc, mob/living/carbon/T)
+ ..()
+ target = T
+ for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7, target))
+ if(!U.welded)
+ pump = U
+ break
+ if(pump)
+ borer = new(pump.loc,target)
+ for(var/i=0, i<11, i++)
+ walk_to(borer, get_step(borer, get_cardinal_dir(borer, T)))
+ if(borer.Adjacent(T))
+ to_chat(T, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
+ T.Stun(4)
+ sleep(50)
+ qdel(borer)
+ sleep(rand(60, 90))
+ to_chat(T, "Primary [rand(1000,9999)] states: [pick("Hello","Hi","You're my slave now!","Don't try to get rid of me...")]")
+ break
+ sleep(4)
+ if(!qdeleted(borer))
+ qdel(borer)
+ qdel(src)
+
+/obj/effect/hallucination/simple/bubblegum
+ name = "Bubblegum"
+ image_icon = 'icons/mob/lavaland/96x96megafauna.dmi'
+ image_state = "bubblegum"
+ px = -32
+
+/obj/effect/hallucination/oh_yeah
+ var/turf/simulated/wall/wall
+ var/obj/effect/hallucination/simple/bubblegum/bubblegum = null
+ var/image/fakebroken
+ var/image/fakerune
+
+/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/T)
+ ..()
+ target = T
+ for(var/turf/simulated/wall/W in range(7,target))
+ wall = W
+ break
+ if(wall)
+ fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER)
+ var/turf/landing = get_turf(target)
+ var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3
+ fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER)
+ fakebroken.override = TRUE
+ if(target.client)
+ target.client.images |= fakebroken
+ target.client.images |= fakerune
+ target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1)
+ bubblegum = new(wall, target)
+ sleep(10) //ominous wait
+ var/charged = FALSE //only get hit once
+ while(get_turf(bubblegum) != landing && target)
+ bubblegum.forceMove(get_step_towards(bubblegum, landing))
+ bubblegum.setDir(get_dir(bubblegum, landing))
+ target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1)
+ shake_camera(target, 2, 1)
+ if(bubblegum.Adjacent(target) && !charged)
+ charged = TRUE
+ target.Weaken(4)
+ target.staminaloss += 40
+ step_away(target, bubblegum)
+ shake_camera(target, 4, 3)
+ target.visible_message("[target] jumps backwards, falling on the ground!","[bubblegum] slams into you!")
+ sleep(2)
+ sleep(30)
+ qdel(bubblegum)
+ qdel(src)
+
+/obj/effect/hallucination/oh_yeah/Destroy()
+ if(target.client)
+ target.client.images.Remove(fakebroken)
+ target.client.images.Remove(fakerune)
+ return ..()
+
/obj/effect/hallucination/singularity_scare
//Singularity moving towards you.
//todo Hide where it moved with fake space images
var/obj/effect/hallucination/simple/singularity/s = null
-/obj/effect/hallucination/singularity_scare/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/singularity_scare/New(loc, mob/living/carbon/T)
target = T
- var/turf/start = T.loc
- var/screen_border = pick(SOUTH,EAST,WEST,NORTH)
+ var/turf/start = get_turf(T)
+ var/screen_border = pick(cardinal)
for(var/i = 0,i<11,i++)
- start = get_step(start,screen_border)
+ start = get_step(start, screen_border)
s = new(start,target)
for(var/i = 0,i<11,i++)
sleep(5)
- s.loc = get_step(get_turf(s),get_dir(s,target))
+ s.loc = get_step(get_turf(s), get_dir(s, target))
s.Show()
s.Eat()
+ addtimer(src, "wake_and_restore", rand(50, 100))
qdel(s)
/obj/effect/hallucination/simple/singularity
@@ -277,50 +392,98 @@ Gunshots/explosions/opening doors/less rare audio (done)
py = -96
/obj/effect/hallucination/simple/singularity/proc/Eat(atom/OldLoc, Dir)
- var/target_dist = get_dist(src,target)
- if(target_dist<=3) //"Eaten"
- target.Sleeping(20)
- target.hal_crit = 1
- target.hal_screwyhud = 1
- spawn(rand(50,100))
- target.SetSleeping(0)
- target.hal_crit = 0
- target.hal_screwyhud = 0
+ var/target_dist = get_dist(src, target)
+ if(target_dist <= 3) //"Eaten"
+ target.hal_screwyhud = SCREWYHUD_CRIT
+ target.SetSleeping(8, no_alert = TRUE)
/obj/effect/hallucination/battle
-/obj/effect/hallucination/battle/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/battle/New(loc, mob/living/carbon/T)
target = T
var/hits = rand(3,6)
switch(rand(1,5))
if(1) //Laser fight
for(var/i=0,i...wabbajack...wabbajack...")
+ target.playsound_local(target,'sound/magic/Staff_Change.ogg', 50, 1, -1)
+ delusion = A
+ target.client.images |= A
+ sleep(duration)
qdel(src)
-/obj/effect/hallucination/fakeattacker/New(loc,var/mob/living/carbon/T)
+/obj/effect/hallucination/self_delusion/Destroy()
+ if(target.client)
+ target.client.images.Remove(delusion)
+ return ..()
+
+/obj/effect/hallucination/fakeattacker/New(loc, mob/living/carbon/T)
+ ..()
target = T
var/mob/living/carbon/human/clone = null
var/clone_weapon = null
@@ -417,25 +626,25 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/health = 100
-/obj/effect/fake_attacker/attackby(var/obj/item/weapon/P as obj, mob/living/user as mob, params)
+/obj/effect/fake_attacker/attackby(obj/item/weapon/P, mob/living/user, params)
step_away(src,my_target,2)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
- my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg'))
+ my_target.playsound_local(src, P.hitsound, 1)
my_target.visible_message("[my_target] flails around wildly.", \
"[my_target] has attacked [src]!")
- src.health -= P.force
+ health -= P.force
return
-/obj/effect/fake_attacker/Crossed(var/mob/M, somenumber)
+/obj/effect/fake_attacker/Crossed(mob/M, somenumber)
if(M == my_target)
step_away(src,my_target,2)
if(prob(30))
for(var/mob/O in oviewers(world.view , my_target))
to_chat(O, "[my_target] stumbles around.")
-/obj/effect/fake_attacker/New(loc,var/mob/living/carbon/T)
+/obj/effect/fake_attacker/New(loc, mob/living/carbon/T)
..()
my_target = T
spawn(300)
@@ -447,25 +656,25 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/fake_attacker/proc/updateimage()
// qdel(src.currentimage)
- if(src.dir == NORTH)
+ if(dir == NORTH)
qdel(src.currentimage)
- src.currentimage = new /image(up,src)
- else if(src.dir == SOUTH)
+ currentimage = new /image(up, src)
+ else if(dir == SOUTH)
qdel(src.currentimage)
- src.currentimage = new /image(down,src)
- else if(src.dir == EAST)
+ currentimage = new /image(down, src)
+ else if(dir == EAST)
qdel(src.currentimage)
- src.currentimage = new /image(right,src)
- else if(src.dir == WEST)
+ currentimage = new /image(right, src)
+ else if(dir == WEST)
qdel(src.currentimage)
- src.currentimage = new /image(left,src)
+ currentimage = new /image(left, src)
my_target << currentimage
/obj/effect/fake_attacker/proc/attack_loop()
while(1)
sleep(rand(5,10))
- if(src.health < 0)
+ if(src.health < 0 || my_target.stat)
collapse()
continue
if(get_dist(src,my_target) > 1)
@@ -474,9 +683,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
updateimage()
else
if(prob(15))
- src.do_attack_animation(my_target)
if(weapon_name)
- my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg'))
+ my_target.playsound_local(my_target, weap.hitsound, 1)
my_target.show_message("[src.name] has attacked [my_target] with [weapon_name]!", 1)
my_target.staminaloss += 30
if(prob(20))
@@ -485,7 +693,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
if(!locate(/obj/effect/overlay) in my_target.loc)
fake_blood(my_target)
else
- my_target << sound(pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg'))
+ my_target.playsound_local(my_target, pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg'), 25, 1, -1)
my_target.show_message("[src.name] has punched [my_target]!", 1)
my_target.staminaloss += 30
if(prob(33))
@@ -498,8 +706,9 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/fake_attacker/proc/collapse()
collapse = 1
updateimage()
+ qdel(src)
-/obj/effect/fake_attacker/proc/fake_blood(var/mob/target)
+/obj/effect/fake_attacker/proc/fake_blood(mob/target)
var/obj/effect/overlay/O = new/obj/effect/overlay(target.loc)
O.name = "blood"
var/image/I = image('icons/effects/blood.dmi',O,"floor[rand(1,7)]",O.dir,1)
@@ -527,7 +736,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/effect/hallucination/bolts
var/list/doors = list()
-/obj/effect/hallucination/bolts/New(loc,var/mob/living/carbon/T,var/door_number=-1) //-1 for sever 1-2 for subtle
+/obj/effect/hallucination/bolts/New(loc, mob/living/carbon/T, door_number = -1) //-1 for sever 1-2 for subtle
target = T
var/image/I = null
var/count = 0
@@ -535,23 +744,26 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
if(count>door_number && door_number>0)
break
count++
- I = image(A.icon,A,"door_locked",layer=A.layer+0.1)
+ I = image(A.icon, get_turf(A), "door_locked", layer=A.layer+0.1)
doors += I
if(target.client)
target.client.images |= I
- sleep(2)
+ target.playsound_local(get_turf(A), 'sound/machines/BoltsDown.ogg',30,0,3)
+ sleep(rand(6,12))
sleep(100)
for(var/image/B in doors)
if(target.client)
target.client.images.Remove(B)
+ target.playsound_local(get_turf(B), 'sound/machines/BoltsUp.ogg',30,0,3)
+ sleep(rand(6,12))
qdel(src)
/obj/effect/hallucination/whispers
/obj/effect/hallucination/whispers/New(loc,var/mob/living/carbon/T)
target = T
- var/speak_messages = list("I'm watching you...","[target.name]!","Go away!","Kchck-Chkck? Kchchck!","Did you hear that?","What did you do ?","Why?","Give me that!","Honk!","HELP!!")
- var/radio_messages = list("Xenos!","Singularity loose!","They are arming the nuke!","They butchered Ian!","H-help!","[pick(teleportlocs)]!!","Where's [target.name]?","Call the shuttle!")
+ var/speak_messages = list("I'm watching you...","[target.name]!","Get out!","Kchck-Chkck? Kchchck!","Did you hear that?","What did you do ?","Why?","Give me that!","Honk!","HELP!!", "EI NATH!!", "RUN!!", "Kill me!","O bidai nabora se'sma!")
+ var/radio_messages = list("Xenos!","Singularity loose!","Comms down!","They are arming the nuke!","They butchered Ian!","H-help!","[pick("Cult", "Wizard", "Ling", "Ops", "Revenant", "Murderer", "Harm", "I hear flashing", "Help")] in [pick(teleportlocs)][prob(50)?"!":"!!"]","Where's [target.name]?","Call the shuttle!","AI rogue!!")
var/list/mob/living/carbon/people = list()
var/list/mob/living/carbon/person = null
@@ -565,7 +777,12 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
person = H
people += H
if(person) //Basic talk
+ var/image/speech_overlay = image('icons/mob/talk.dmi', person, "h0", layer = ABOVE_MOB_LAYER)
target.hear_say(pick(speak_messages),language = pick(person.languages),speaker = person)
+ if(target.client)
+ target.client.images |= speech_overlay
+ sleep(30)
+ target.client.images.Remove(speech_overlay)
else // Radio talk
var/list/humans = list()
for(var/mob/living/carbon/human/H in living_mob_list)
@@ -578,76 +795,93 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/effect/hallucination/message/New(loc,var/mob/living/carbon/T)
target = T
- var/chosen = pick("The light burns you!", \
- "You don't feel like yourself.", \
- "Unknown has punched [target]!", \
- "You hear something squeezing through the ducts...", \
- "You hear a distant scream.", \
- "You feel invincible, nothing can hurt you!", \
- "[target] sneezes.", \
- "You feel faint.", \
- "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]", \
+ var/chosen = pick("The light burns you!",
+ "You don't feel like yourself.",
+ "Unknown has punched [target]!",
+ "You hear something squeezing through the ducts...",
+ "You hear a distant scream.",
+ "You feel invincible, nothing can hurt you!",
+ "You feel a tiny prick!",
+ "[target] sneezes.",
+ "You feel faint.",
+ "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]",
"You can see...everything!")
to_chat(target, chosen)
qdel(src)
-/mob/living/carbon/proc/hallucinate(var/hal_type) // Todo -> proc / defines
+/mob/living/carbon/proc/hallucinate(hal_type) // Todo -> proc / defines
switch(hal_type)
if("xeno")
- new /obj/effect/hallucination/xeno_attack(src.loc,src)
+ new /obj/effect/hallucination/xeno_attack(loc, src)
+ if("borer")
+ new /obj/effect/hallucination/borer(loc, src)
if("singulo")
- new /obj/effect/hallucination/singularity_scare(src.loc,src)
+ new /obj/effect/hallucination/singularity_scare(loc, src)
+ if("koolaid")
+ new /obj/effect/hallucination/oh_yeah(loc, src)
if("battle")
- new /obj/effect/hallucination/battle(src.loc,src)
+ new /obj/effect/hallucination/battle(loc, src)
if("flood")
- new /obj/effect/hallucination/fake_flood(src.loc,src)
+ new /obj/effect/hallucination/fake_flood(loc, src)
if("delusion")
- new /obj/effect/hallucination/delusion(src.loc,src)
+ new /obj/effect/hallucination/delusion(loc, src)
+ if("self_delusion")
+ new /obj/effect/hallucination/self_delusion(loc, src)
if("fake")
- new /obj/effect/hallucination/fakeattacker(src.loc,src)
+ new /obj/effect/hallucination/fakeattacker(loc, src)
if("bolts")
- new /obj/effect/hallucination/bolts(src.loc,src)
+ new /obj/effect/hallucination/bolts(loc, src)
if("bolts_minor")
- new /obj/effect/hallucination/bolts(src.loc,src,rand(1,2))
+ new /obj/effect/hallucination/bolts(loc,src, rand(1,2))
if("whispers")
- new /obj/effect/hallucination/whispers(src.loc,src)
+ new /obj/effect/hallucination/whispers(loc, src)
if("message")
- new /obj/effect/hallucination/message(src.loc,src)
+ new /obj/effect/hallucination/message(loc, src)
+ if("items_other")
+ new /obj/effect/hallucination/items_other(src.loc,src)
if("sounds")
//Strange audio
// to_chat(src, "Strange Audio")
switch(rand(1,18))
if(1)
- src << 'sound/machines/airlock.ogg'
+ playsound_local(null,'sound/machines/airlock.ogg', 15, 1)
if(2)
if(prob(50))
- src << 'sound/effects/Explosion1.ogg'
+ playsound_local(null,'sound/effects/Explosion1.ogg', 50, 1)
else
- src << 'sound/effects/Explosion2.ogg'
+ playsound_local(null, 'sound/effects/Explosion2.ogg', 50, 1)
if(3)
- src << 'sound/effects/explosionfar.ogg'
+ playsound_local(null, 'sound/effects/explosionfar.ogg', 50, 1)
if(4)
- src << 'sound/effects/Glassbr1.ogg'
+ playsound_local(null, pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg'), 50, 1)
if(5)
- src << 'sound/effects/Glassbr2.ogg'
+ playsound_local(null, 'sound/weapons/ring.ogg', 35)
+ sleep(15)
+ playsound_local(null, 'sound/weapons/ring.ogg', 35)
+ sleep(15)
+ playsound_local(null, 'sound/weapons/ring.ogg', 35)
if(6)
- src << 'sound/effects/Glassbr3.ogg'
+ playsound_local(null, 'sound/magic/Summon_guns.ogg', 50, 1)
if(7)
- src << 'sound/machines/twobeep.ogg'
+ playsound_local(null, 'sound/machines/Alarm.ogg', 100, 0)
if(8)
- src << 'sound/machines/windowdoor.ogg'
+ playsound_local(null, 'sound/voice/bfreeze.ogg', 35, 0)
if(9)
//To make it more realistic, I added two gunshots (enough to kill)
- src << 'sound/weapons/Gunshot.ogg'
+ playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1)
spawn(rand(10,30))
- src << 'sound/weapons/Gunshot.ogg'
+ playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1)
+ sleep(rand(5,10))
+ playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1)
if(10)
- src << 'sound/weapons/smash.ogg'
+ playsound_local(null, 'sound/effects/pray_chaplain.ogg', 50)
if(11)
//Same as above, but with tasers.
- src << 'sound/weapons/Taser.ogg'
+ playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1)
spawn(rand(10,30))
- src << 'sound/weapons/Taser.ogg'
+ playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1)
+ sleep(rand(5,10))
+ playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1)
//Rare audio
if(12)
//These sounds are (mostly) taken from Hidden: Source
@@ -656,40 +890,110 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
- src << pick(creepyasssounds)
+ playsound_local(null, pick(creepyasssounds), 50, 1)
if(13)
to_chat(src, "You feel a tiny prick!")
if(14)
to_chat(src, "Priority Announcement
")
to_chat(src, "
The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.
")
- src << sound('sound/AI/shuttledock.ogg')
+ playsound_local(null, 'sound/AI/shuttledock.ogg', 100)
if(15)
- src << 'sound/items/Welder.ogg'
+ playsound_local(null, 'sound/items/Welder.ogg', 15, 1)
+ sleep(105)
+ playsound_local(null, 'sound/items/Welder2.ogg', 15, 1)
+ sleep(15)
+ playsound_local(null, 'sound/items/Ratchet.ogg', 15, 1)
if(16)
- src << 'sound/items/Screwdriver.ogg'
+ playsound_local(null, 'sound/items/Screwdriver.ogg', 15, 1)
+ sleep(rand(10,30))
+ for(var/i = rand(1,3), i>0, i--)
+ playsound_local(null, 'sound/weapons/empty.ogg', 15, 1)
+ sleep(rand(10,30))
+ playsound_local(null, 'sound/machines/airlockforced.ogg', 15, 1)
if(17)
- src << 'sound/weapons/saberon.ogg'
+ playsound_local(null, 'sound/weapons/saberon.ogg', 35, 1)
if(18)
- src << 'sound/weapons/saberoff.ogg'
+ to_chat(src, "Biohazard Alert
")
+ to_chat(src, "
Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.
")
+ playsound_local(null, 'sound/AI/outbreak5.ogg')
+ if(19) //Tesla loose!
+ playsound_local(null, 'sound/magic/lightningbolt.ogg', 35, 1)
+ sleep(20)
+ playsound_local(null, 'sound/magic/lightningbolt.ogg', 65, 1)
+ sleep(20)
+ playsound_local(null, 'sound/magic/lightningbolt.ogg', 100, 1)
+ if(20) //AI is doomsdaying!
+ to_chat(src, "Anomaly Alert
")
+ to_chat(src, "
Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.
")
+ playsound_local(null, 'sound/AI/aimalf.ogg')
if("hudscrew")
//Screwy HUD
-// to_chat(src, "Screwy HUD")
- hal_screwyhud = pick(1,2,3,3,4,4)
- spawn(rand(100,250))
- hal_screwyhud = 0
+ hal_screwyhud = pick(SCREWYHUD_NONE, SCREWYHUD_CRIT, SCREWYHUD_DEAD, SCREWYHUD_HEALTHY)
+ sleep(rand(100,250))
+ hal_screwyhud = SCREWYHUD_NONE
+ if("fake_alert")
+ var/alert_type = pick("oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","tox_in_air","newlaw","nutrition","charge","weightless","fire","locked","hacked","temp","pressure")
+ switch(alert_type)
+ if("oxy")
+ throw_alert("oxy", /obj/screen/alert/oxy, override = TRUE)
+ if("not_enough_tox")
+ throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox, override = TRUE)
+ if("not_enough_co2")
+ throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2, override = TRUE)
+ if("too_much_oxy")
+ throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy, override = TRUE)
+ if("too_much_co2")
+ throw_alert("too_much_co2", /obj/screen/alert/too_much_co2, override = TRUE)
+ if("tox_in_air")
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air, override = TRUE)
+ if("nutrition")
+ if(prob(50))
+ throw_alert("nutrition", /obj/screen/alert/fat, override = TRUE)
+ else
+ throw_alert("nutrition", /obj/screen/alert/starving, override = TRUE)
+ if("weightless")
+ throw_alert("weightless", /obj/screen/alert/weightless, override = TRUE)
+ if("fire")
+ throw_alert("fire", /obj/screen/alert/fire, override = TRUE)
+ if("temp")
+ if(prob(50))
+ throw_alert("temp", /obj/screen/alert/hot, 3, override = TRUE)
+ else
+ throw_alert("temp", /obj/screen/alert/cold, 3, override = TRUE)
+ if("pressure")
+ if(prob(50))
+ throw_alert("pressure", /obj/screen/alert/highpressure, 2, override = TRUE)
+ else
+ throw_alert("pressure", /obj/screen/alert/lowpressure, 2, override = TRUE)
+ //BEEP BOOP I AM A ROBOT
+ if("newlaw")
+ throw_alert("newlaw", /obj/screen/alert/newlaw, override = TRUE)
+ if("locked")
+ throw_alert("locked", /obj/screen/alert/locked, override = TRUE)
+ if("hacked")
+ throw_alert("hacked", /obj/screen/alert/hacked, override = TRUE)
+ if("charge")
+ throw_alert("charge",/obj/screen/alert/emptycell, override = TRUE)
+ sleep(rand(100,200))
+ clear_alert(alert_type, clear_override = TRUE)
if("items")
//Strange items
// to_chat(src, "Traitor Items")
if(!halitem)
halitem = new
var/list/slots_free = list(ui_lhand,ui_rhand)
- if(l_hand) slots_free -= ui_lhand
- if(r_hand) slots_free -= ui_rhand
+ if(l_hand)
+ slots_free -= ui_lhand
+ if(r_hand)
+ slots_free -= ui_rhand
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src
- if(!H.belt) slots_free += ui_belt
- if(!H.l_store) slots_free += ui_storage1
- if(!H.r_store) slots_free += ui_storage2
+ if(!H.belt)
+ slots_free += ui_belt
+ if(!H.l_store)
+ slots_free += ui_storage1
+ if(!H.r_store)
+ slots_free += ui_storage2
if(slots_free.len)
halitem.screen_loc = pick(slots_free)
halitem.layer = 50
@@ -726,7 +1030,6 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
qdel(halitem)
if("dangerflash")
//Flashes of danger
-// to_chat(src, "Danger Flash")
if(!halimage)
var/list/possible_points = list()
for(var/turf/simulated/floor/F in view(src,world.view))
@@ -734,31 +1037,38 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
if(possible_points.len)
var/turf/simulated/floor/target = pick(possible_points)
- switch(rand(1,3))
+ switch(rand(1,4))
if(1)
-// to_chat(src, "Space")
halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
if(2)
-// to_chat(src, "Fire")
- halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
+ halimage = image('icons/turf/floors/lava.dmi',target,"smooth",TURF_LAYER)
if(3)
-// to_chat(src, "C4")
+ halimage = image('icons/turf/floors/Chasms.dmi',target,"smooth",TURF_LAYER)
+ if(4)
halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
- if(client) client.images += halimage
- spawn(rand(10,50)) //Only seen for a brief moment.
- if(client) client.images -= halimage
- halimage = null
+ if(client)
+ client.images += halimage
+ sleep(rand(40,60)) //Only seen for a brief moment.
+ if(client)
+ client.images -= halimage
+ halimage = null
if("death")
- //Fake death
- Sleeping(20)
- hal_crit = 1
- hal_screwyhud = 1
- spawn(rand(50,100))
- SetSleeping(0)
- hal_crit = 0
- hal_screwyhud = 0
+ hal_screwyhud = SCREWYHUD_DEAD
+ SetSleeping(20, no_alert = TRUE)
+ if(prob(50))
+ var/list/dead_people
+ for(var/mob/dead/observer/G in player_list)
+ dead_people += G
+ var/mob/dead/observer/fakemob = pick(dead_people)
+ if(fakemob)
+ sleep(rand(30, 60))
+ to_chat(src, "[fakemob.name](FOLLOW) [pick("complains", "moans", "whines", "laments", "blubbers", "salts")], \"[pick("rip","welcome [name]","you too?","is the AI malf?",\
+ "i[prob(50)?" fucking":""] hate [pick("blood cult", "clock cult", "revenants", "abductors","double agents","viruses","badmins","you")]")]\"")
+ sleep(rand(50,70))
+ hal_screwyhud = SCREWYHUD_NONE
+ SetSleeping(0)
if("husks")
if(!halbody)
var/list/possible_points = list()
@@ -768,17 +1078,19 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
var/turf/simulated/floor/target = pick(possible_points)
switch(rand(1,4))
if(1)
- var/image/body = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ var/image/body = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER)
var/matrix/M = matrix()
M.Turn(90)
body.transform = M
halbody = body
if(2,3)
- halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ halbody = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER)
if(4)
- halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
+ halbody = image('icons/mob/alien.dmi', target, "alienother", TURF_LAYER)
- if(client) client.images += halbody
- spawn(rand(50,80)) //Only seen for a brief moment.
- if(client) client.images -= halbody
+ if(client)
+ client.images += halbody
+ spawn(rand(30,50)) //Only seen for a brief moment.
+ if(client)
+ client.images -= halbody
halbody = null
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index fec4da6fae4..2d1fe34c06c 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -527,9 +527,9 @@
H.healths.icon_state = "health7"
else
switch(H.hal_screwyhud)
- if(1) H.healths.icon_state = "health6"
- if(2) H.healths.icon_state = "health7"
- if(5) H.healths.icon_state = "health0"
+ if(SCREWYHUD_CRIT) H.healths.icon_state = "health6"
+ if(SCREWYHUD_DEAD) H.healths.icon_state = "health7"
+ if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0"
else
switch(100 - ((flags & NO_PAIN) ? 0 : H.traumatic_shock) - H.staminaloss)
if(100 to INFINITY) H.healths.icon_state = "health0"
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index 5ca23f89f4f..5f74f202603 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -13,7 +13,7 @@
amount = amount * species.stun_mod
..()
-/mob/living/carbon/human/SetSleeping(amount, updating = 1)
+/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE)
if(species)
amount = amount * species.stun_mod
..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 91661304144..da764cafda3 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -345,7 +345,7 @@
if(..())
handle_dreams()
adjustStaminaLoss(-10)
- if(prob(10) && health && !hal_crit)
+ if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT)
spawn(0)
emote("snore")
// Keep SSD people asleep
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index e95381d19cf..30fe030bdcb 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -354,19 +354,19 @@
// SLEEPING
-/mob/living/Sleeping(amount, updating = 1)
- SetSleeping(max(sleeping, amount), updating)
+/mob/living/Sleeping(amount, updating = 1, no_alert = FALSE)
+ SetSleeping(max(sleeping, amount), updating, no_alert)
-/mob/living/SetSleeping(amount, updating = 1)
+/mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE)
sleeping = max(amount, 0)
- update_sleeping_effects()
+ update_sleeping_effects(no_alert)
if(updating)
update_stat()
update_canmove()
-/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1)
+/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1, no_alert = FALSE)
var/new_value = directional_bounded_sum(sleeping, amount, bound_lower, bound_upper)
- SetSleeping(new_value, updating)
+ SetSleeping(new_value, updating, no_alert)
// SLOWED
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 59b7077e79e..257a4bc87c1 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -30,9 +30,10 @@
else
clear_fullscreen("nearsighted")
-/mob/living/update_sleeping_effects()
+/mob/living/update_sleeping_effects(no_alert = FALSE)
if(sleeping)
- throw_alert("asleep", /obj/screen/alert/asleep)
+ if(!no_alert)
+ throw_alert("asleep", /obj/screen/alert/asleep)
else
clear_alert("asleep")
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index db8191aed53..e5a33e76de3 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/sound/effects/pray_chaplain.ogg b/sound/effects/pray_chaplain.ogg
new file mode 100644
index 00000000000..1b543275311
Binary files /dev/null and b/sound/effects/pray_chaplain.ogg differ