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