diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 859f3e37756..21406c0e43a 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -9,6 +9,7 @@ #define INVESTIGATE_SUPERMATTER "supermatter" #define INVESTIGATE_TELESCI "telesci" #define INVESTIGATE_WIRES "wires" +#define INVESTIGATE_HALLUCINATIONS "hallucinations" //Individual logging defines #define INDIVIDUAL_ATTACK_LOG "Attack log" diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 7b399879c57..4fe57be4429 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -942,7 +942,7 @@ var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations if(!usr) return - if(!C) + if(QDELETED(C)) to_chat(usr, "Mob doesn't exist anymore") return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 007f8e42bdc..94047727bc0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -233,9 +233,13 @@ return else /*if(src.justzap)*/ return - else if(user.hallucination > 50 && ishuman(user) && prob(4) && !operating) - hallucinate_shock(user) - return + else if(user.hallucinating() && ishuman(user) && prob(4) && !operating) + var/mob/living/carbon/human/H = user + if(H.gloves) + var/obj/item/clothing/gloves/G = H.gloves + if(G.siemens_coefficient)//not insulated + hallucinate_shock(H) + return if (cyclelinkedairlock) if (!shuttledocked && !emergency && !cyclelinkedairlock.shuttledocked && !cyclelinkedairlock.emergency && allowed(user)) if(cyclelinkedairlock.operating) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 0e91b3c0f12..d0ee90e4d39 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -5,7 +5,7 @@ F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
" -/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY) ) +/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS) ) set name = "Investigate" set category = "Admin" if(!holder) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 8633b89f006..2b8fe4b0642 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -60,9 +60,14 @@ GLOBAL_LIST_INIT(hallucinations_major, list( var/halpick = pick(current) new halpick(src, FALSE) +/mob/living/carbon/proc/set_screwyhud(hud_type) + hal_screwyhud = hud_type + update_health_hud() + /datum/hallucination var/mob/living/carbon/target var/cost = 5 //affects the amount of hallucination reduced, and cooldown until the next hallucination + var/feedback_details //extra info for investigate /datum/hallucination/New(mob/living/carbon/T, forced = TRUE) set waitfor = 0 @@ -72,9 +77,13 @@ GLOBAL_LIST_INIT(hallucinations_major, list( target.next_hallucination = world.time + (rand(cost * 0.5, cost * 3) * 10) /datum/hallucination/proc/wake_and_restore() - target.hal_screwyhud = SCREWYHUD_NONE + target.set_screwyhud(SCREWYHUD_NONE) target.SetSleeping(0) +/datum/hallucination/Destroy() + target.investigate_log("was afflicted with a hallucination of type [type]. [feedback_details]", INVESTIGATE_HALLUCINATIONS) + return ..() + /obj/effect/hallucination invisibility = INVISIBILITY_OBSERVER var/mob/living/carbon/target = null @@ -152,6 +161,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( if(!U.welded) center = get_turf(U) break + feedback_details += "Vent Coords: [center.x],[center.y],[center.z]" flood_images += image(image_icon,center,image_state,MOB_LAYER) flood_turfs += center if(target.client) target.client.images |= flood_images @@ -217,6 +227,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( if(!U.welded) pump = U break + feedback_details += "Vent Coords: [pump.x],[pump.y],[pump.z]" if(pump) xeno = new(pump.loc,target) sleep(10) @@ -265,6 +276,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( break if(!wall) return INITIALIZE_HINT_QDEL + feedback_details += "Source: [wall.x],[wall.y],[wall.z]" fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER) var/turf/landing = get_turf(target) @@ -317,6 +329,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( var/screen_border = pick(SOUTH,EAST,WEST,NORTH) for(var/i in 1 to 13) start = get_step(start,screen_border) + feedback_details += "Source: [start.x],[start.y],[start.z]" s = new(start,target) s.parent = src for(var/i in 1 to 13) @@ -337,18 +350,21 @@ GLOBAL_LIST_INIT(hallucinations_major, list( /obj/effect/hallucination/simple/singularity/proc/Eat(atom/OldLoc, Dir) var/target_dist = get_dist(src,target) if(target_dist<=3) //"Eaten" - target.hal_screwyhud = SCREWYHUD_DEAD + target.set_screwyhud(SCREWYHUD_DEAD) target.SetUnconscious(160) addtimer(CALLBACK(parent, /datum/hallucination/.proc/wake_and_restore), rand(30, 50)) /datum/hallucination/battle cost = 15 -/datum/hallucination/battle/New(mob/living/carbon/T, forced = TRUE) +/datum/hallucination/battle/New(mob/living/carbon/T, forced = TRUE, battle_type) ..() var/hits = rand(3,6) - switch(rand(1,5)) - if(1) //Laser fight + if(!battle_type) + battle_type = pick("laser","esword","gun","stunprod","bomb") + feedback_details += "Type: [battle_type]" + switch(battle_type) + if("laser") //Laser fight for(var/i in 1 to hits) target.playsound_local(null, 'sound/weapons/laser.ogg', 25, 1) if(prob(50)) @@ -357,14 +373,14 @@ GLOBAL_LIST_INIT(hallucinations_major, list( addtimer(CALLBACK(target, /mob/.proc/playsound_local, null, 'sound/weapons/effects/searwall.ogg', 25, 1), rand(10,20)) sleep(rand(CLICK_CD_RANGE, CLICK_CD_RANGE + 8)) target.playsound_local(null, get_sfx("bodyfall"), 25, 1) - if(2) //Esword fight + if("esword") //Esword fight target.playsound_local(null, 'sound/weapons/saberon.ogg',15, 1) for(var/i=0,idoor_number && door_number>0) break @@ -734,7 +759,9 @@ GLOBAL_LIST_INIT(hallucinations_major, list( people += H if(person) //Basic talk var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER) - to_chat(target, target.compose_message(person,understood_language,pick(speak_messages),null,person.get_spans())) + var/message = target.compose_message(person,understood_language,pick(speak_messages),null,person.get_spans()) + feedback_details += "Type: Talk, Source: [person.real_name], Message: [message]" + to_chat(target, message) if(target.client) target.client.images |= speech_overlay sleep(30) @@ -744,7 +771,9 @@ GLOBAL_LIST_INIT(hallucinations_major, list( for(var/mob/living/carbon/human/H in GLOB.living_mob_list) humans += H person = pick(humans) - to_chat(target, target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans())) + var/message = target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans()) + feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]" + to_chat(target, message) qdel(src) /datum/hallucination/message @@ -763,43 +792,48 @@ GLOBAL_LIST_INIT(hallucinations_major, list( "You're hallucinating.", \ //Direct advice "[pick_list_replacements(HAL_LINES_FILE, "advice")]") + feedback_details += "Message: [chosen]" to_chat(target, chosen) qdel(src) /datum/hallucination/sounds cost = 15 -/datum/hallucination/sounds/New(mob/living/carbon/T, forced = TRUE) +/datum/hallucination/sounds/New(mob/living/carbon/T, forced = TRUE, sound_type) ..() + if(!sound_type) + sound_type = pick("airlock","explosion","far_explosion","glass","phone","summon_guns","alarm","beepsky","hallelujah","creepy","ratvar","shuttle_dock", + "wall_decon","door_hack","esword","blob_alert","tesla","malf_ai") + feedback_details += "Type: [sound_type]" //Strange audio - switch(rand(1,20)) - if(1) + switch(sound_type) + if("airlock") target.playsound_local(null,'sound/machines/airlock.ogg', 15, 1) - if(2) + if("explosion") if(prob(50)) target.playsound_local(null,'sound/effects/explosion1.ogg', 50, 1) else target.playsound_local(null, 'sound/effects/explosion2.ogg', 50, 1) - if(3) + if("far_explosion") target.playsound_local(null, 'sound/effects/explosionfar.ogg', 50, 1) - if(4) + if("glass") target.playsound_local(null, pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg'), 50, 1) - if(5) + if("phone") target.playsound_local(null, 'sound/weapons/ring.ogg', 35) sleep(15) target.playsound_local(null, 'sound/weapons/ring.ogg', 35) sleep(15) target.playsound_local(null, 'sound/weapons/ring.ogg', 35) - if(6) + if("summon_guns") target.playsound_local(null, 'sound/magic/summon_guns.ogg', 50, 1) - if(7) + if("alarm") target.playsound_local(null, 'sound/machines/alarm.ogg', 100, 0) - if(8) + if("beepsky") target.playsound_local(null, 'sound/voice/bfreeze.ogg', 35, 0) - if(9) + if("hallelujah") target.playsound_local(null, 'sound/effects/pray_chaplain.ogg', 50) //Rare audio - if(10) + if("creepy") //These sounds are (mostly) taken from Hidden: Source var/static/list/hallucinations_creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ @@ -807,42 +841,42 @@ GLOBAL_LIST_INIT(hallucinations_major, list( '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') target.playsound_local(null, pick(hallucinations_creepyasssounds), 50, 1) - if(11) + if("ratvar") target.playsound_local(null, 'sound/effects/ratvar_rises.ogg', 100) sleep(150) target.playsound_local(null, 'sound/effects/ratvar_reveal.ogg', 100) - if(12) + if("shuttle_dock") to_chat(target, "

Priority Announcement

") to_chat(target, "

The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.

") target.playsound_local(null, 'sound/ai/shuttledock.ogg', 100) //Deconstructing a wall - if(13) + if("wall_decon") target.playsound_local(null, 'sound/items/welder.ogg', 15, 1) sleep(105) target.playsound_local(null, 'sound/items/welder2.ogg', 15, 1) sleep(15) target.playsound_local(null, 'sound/items/ratchet.ogg', 15, 1) //Hacking a door - if(14) + if("door_hack") target.playsound_local(null, 'sound/items/screwdriver.ogg', 15, 1) sleep(rand(10,30)) for(var/i = rand(1,3), i>0, i--) target.playsound_local(null, 'sound/weapons/empty.ogg', 15, 1) sleep(rand(10,30)) target.playsound_local(null, 'sound/machines/airlockforced.ogg', 15, 1) - if(15) + if("esword") target.playsound_local(null, 'sound/weapons/saberon.ogg',35,1) - if(16) + if("blob_alert") to_chat(target, "

Biohazard Alert

") to_chat(target, "

Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.

") target.playsound_local(null, 'sound/ai/outbreak5.ogg', 100, 0) - if(17) //Tesla loose! + if("tesla") //Tesla loose! target.playsound_local(null, 'sound/magic/lightningbolt.ogg', 35, 1) sleep(20) target.playsound_local(null, 'sound/magic/lightningbolt.ogg', 65, 1) sleep(20) target.playsound_local(null, 'sound/magic/lightningbolt.ogg', 100, 1) - if(18) //AI is doomsdaying! + if("malf_ai") //AI is doomsdaying! to_chat(target, "

Anomaly Alert

") to_chat(target, "

Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.

") target.playsound_local(null, 'sound/ai/aimalf.ogg', 100, 0) @@ -854,9 +888,10 @@ GLOBAL_LIST_INIT(hallucinations_major, list( /datum/hallucination/hudscrew/New(mob/living/carbon/T, forced = TRUE) ..() //Screwy HUD - target.hal_screwyhud = pick(SCREWYHUD_CRIT,SCREWYHUD_DEAD,SCREWYHUD_HEALTHY) + target.set_screwyhud(pick(SCREWYHUD_CRIT,SCREWYHUD_DEAD,SCREWYHUD_HEALTHY)) + feedback_details += "Type: [target.hal_screwyhud]" sleep(rand(100,250)) - target.hal_screwyhud = SCREWYHUD_NONE + target.set_screwyhud(SCREWYHUD_NONE) qdel(src) /datum/hallucination/fake_alert @@ -867,6 +902,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( var/alert_type = pick("not_enough_oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","too_much_tox","newlaw","nutrition","charge","weightless","fire","locked","hacked","temphot","tempcold","pressure") if(specific) alert_type = specific + feedback_details += "Type: [alert_type]" switch(alert_type) if("oxy") target.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy, override = TRUE) @@ -962,6 +998,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( target.halitem.icon = 'icons/obj/grenade.dmi' target.halitem.icon_state = "flashbang1" target.halitem.name = "Flashbang" + feedback_details += "Type: [target.halitem.name]" if(target.client) target.client.screen += target.halitem QDEL_IN(target.halitem, rand(150, 350)) qdel(src) @@ -1006,7 +1043,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( /datum/hallucination/death/New(mob/living/carbon/T, forced = TRUE) set waitfor = 0 ..() - target.hal_screwyhud = SCREWYHUD_DEAD + target.set_screwyhud(SCREWYHUD_DEAD) target.Knockdown(300) target.silent += 10 var/area/area = get_area(target) @@ -1025,7 +1062,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( to_chat(target, "DEAD: [fakemob.name] says, \"[pick("rip","hey [target.first_name()]","you too?","is the AI rogue?",\ "i[prob(50)?" fucking":""] hate [pick("blood cult", "clock cult", "revenants", "abductors","double agents","viruses","badmins","you")]")]\"") sleep(rand(70,90)) - target.hal_screwyhud = SCREWYHUD_NONE + target.set_screwyhud(SCREWYHUD_NONE) target.SetKnockdown(0) target.silent = 0 qdel(src) @@ -1100,6 +1137,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( startlocs += T var/turf/start = pick(startlocs) var/proj_type = pick(subtypesof(/obj/item/projectile/hallucination)) + feedback_details += "Type: [proj_type]" var/obj/item/projectile/hallucination/H = new proj_type(start) target.playsound_local(start, H.hal_fire_sound, 60, 1) H.hal_target = target diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 1c07c408d38..3ae1b198f80 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -234,6 +234,12 @@ /mob/living/carbon/is_muzzled() return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) +/mob/living/carbon/hallucinating() + if(hallucination) + return TRUE + else + return FALSE + /mob/living/carbon/resist_buckle() if(restrained()) changeNext_move(CLICK_CD_BREAKOUT) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a704c2e43f0..46f5db920bc 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -325,6 +325,9 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return B.eye_blind return 0 +/mob/proc/hallucinating() + return FALSE + /proc/is_special_character(mob/M) // returns 1 for special characters and 2 for heroes of gamemode //moved out of admins.dm because things other than admin procs were calling this. if(!SSticker.HasRoundStarted()) return 0 diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 27cad406fab..3811512a021 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -101,9 +101,11 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "chem_dispenser", name, 550, 550, master_ui, state) + if(user.hallucinating()) + ui.set_autoupdate(FALSE) //to not ruin the immersion by constantly changing the fake chemicals ui.open() -/obj/machinery/chem_dispenser/ui_data() +/obj/machinery/chem_dispenser/ui_data(mob/user) var/data = list() data["amount"] = amount data["energy"] = cell.charge ? cell.charge * powerefficiency : "0" //To prevent NaN in the UI. @@ -128,10 +130,16 @@ data["beakerTransferAmounts"] = null var chemicals[0] + var/is_hallucinating = FALSE + if(user.hallucinating()) + is_hallucinating = TRUE for(var/re in dispensable_reagents) var/datum/reagent/temp = GLOB.chemical_reagents_list[re] if(temp) - chemicals.Add(list(list("title" = temp.name, "id" = temp.id))) + var/chemname = temp.name + if(is_hallucinating && prob(5)) + chemname = "[pick_list_replacements("hallucination.json", "chemicals")]" + chemicals.Add(list(list("title" = chemname, "id" = temp.id))) data["chemicals"] = chemicals return data diff --git a/strings/hallucination.json b/strings/hallucination.json index 03c2a21b854..b28c70db4a6 100644 --- a/strings/hallucination.json +++ b/strings/hallucination.json @@ -198,4 +198,32 @@ "You have my permission. Do it." ] + "chemicals": [ + "Ooze", + "Fire", + "Earth", + "Lightning", + "Air", + "Magic", + "Spiders", + "Button", + "Surprise", + "Happiness", + "Despair", + "Blood", + "Awesome", + "Infinity", + "Electronics", + "Time", + "Space", + "Pain", + "Guts", + "Life", + "Death", + "Phlebotinium", + "Mana", + "Energy", + "?????" + ] + }