/* Morgue stuff * Contains: * Morgue * Morgue tray * Crematorium * Creamatorium * Crematorium tray * Crematorium button */ /* * Bodycontainer * Parent class for morgue and crematorium * For overriding only */ /obj/structure/bodycontainer icon = 'icons/obj/stationobjs.dmi' icon_state = "morgue1" density = TRUE anchored = TRUE max_integrity = 400 var/obj/structure/tray/connected = null var/locked = FALSE var/opendir = SOUTH /obj/structure/bodycontainer/Destroy() open() if(connected) qdel(connected) connected = null return ..() /obj/structure/bodycontainer/on_log(login) ..() update_icon() /obj/structure/bodycontainer/update_icon() return /obj/structure/bodycontainer/relaymove(mob/user) if(user.stat || !isturf(loc)) return open() /obj/structure/bodycontainer/attack_paw(mob/user) return src.attack_hand(user) /obj/structure/bodycontainer/attack_hand(mob/user) if(locked) to_chat(user, "It's locked.") return if(!connected) to_chat(user, "That doesn't appear to have a tray.") return if(connected.loc == src) open() else close() add_fingerprint(user) /obj/structure/bodycontainer/attack_robot(mob/user) if(!user.Adjacent(src)) return return attack_hand(user) /obj/structure/bodycontainer/attackby(obj/P, mob/user, params) add_fingerprint(user) if(istype(P, /obj/item/pen)) var/t = stripped_input(user, "What would you like the label to be?", text("[]", name), null) if (user.get_active_held_item() != P) return if ((!in_range(src, usr) && src.loc != user)) return if (t) name = text("[]- '[]'", initial(name), t) else name = initial(name) else return ..() /obj/structure/bodycontainer/deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/metal (loc, 5) qdel(src) /obj/structure/bodycontainer/container_resist(mob/living/user) open() /obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O) to_chat(user, "You slam yourself into the side of [O].") container_resist(user) /obj/structure/bodycontainer/proc/open() playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) var/turf/T = get_step(src, opendir) for(var/atom/movable/AM in src) AM.forceMove(T) update_icon() /obj/structure/bodycontainer/proc/close() playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) for(var/atom/movable/AM in connected.loc) if(!AM.anchored || AM == connected) AM.forceMove(src) update_icon() /obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 2) /* * Morgue */ /obj/structure/bodycontainer/morgue name = "morgue" desc = "Used to keep bodies in until someone fetches them." icon_state = "morgue1" opendir = EAST /obj/structure/bodycontainer/morgue/New() connected = new/obj/structure/tray/m_tray(src) connected.connected = src ..() /obj/structure/bodycontainer/morgue/update_icon() if (!connected || connected.loc != src) // Open or tray is gone. icon_state = "morgue0" else if(contents.len == 1) // Empty icon_state = "morgue1" else icon_state = "morgue2" // Dead, brainded mob. var/list/compiled = recursive_mob_check(src, 0, 0) // Search for mobs in all contents. if(!length(compiled)) // No mobs? icon_state = "morgue3" return for(var/mob/living/M in compiled) if(M.client && !M.suiciding) icon_state = "morgue4" // Cloneable break /obj/item/paper/guides/jobs/medical/morgue name = "morgue memo" info = "Since this station's medbay never seems to fail to be staffed by the mindless monkeys meant for genetics experiments, I'm leaving a reminder here for anyone handling the pile of cadavers the quacks are sure to leave.

Red lights mean there's a plain ol' dead body inside.

Yellow lights mean there's non-body objects inside.
Probably stuff pried off a corpse someone grabbed, or if you're lucky it's stashed booze.

Green lights mean the morgue system detects the body may be able to be cloned.

I don't know how that works, but keep it away from the kitchen and go yell at the geneticists.

- CentCom medical inspector" /* * Crematorium */ GLOBAL_LIST_EMPTY(crematoriums) /obj/structure/bodycontainer/crematorium name = "crematorium" desc = "A human incinerator. Works well on barbeque nights." icon_state = "crema1" opendir = SOUTH var/id = 1 /obj/structure/bodycontainer/crematorium/attack_robot(mob/user) //Borgs can't use crematoriums without help to_chat(user, "[src] is locked against you.") return /obj/structure/bodycontainer/crematorium/Destroy() GLOB.crematoriums.Remove(src) return ..() /obj/structure/bodycontainer/crematorium/New() connected = new/obj/structure/tray/c_tray(src) connected.connected = src GLOB.crematoriums.Add(src) ..() /obj/structure/bodycontainer/crematorium/update_icon() if(!connected || connected.loc != src) icon_state = "crema0" else if(src.contents.len > 1) src.icon_state = "crema2" else src.icon_state = "crema1" if(locked) src.icon_state = "crema_active" return /obj/structure/bodycontainer/crematorium/proc/cremate(mob/user) if(locked) return //don't let you cremate something twice or w/e // Make sure we don't delete the actual morgue and its tray var/list/conts = GetAllContents() - src - connected if(!conts.len) audible_message("You hear a hollow crackle.") return else audible_message("You hear a roar as the crematorium activates.") locked = TRUE update_icon() for(var/mob/living/M in conts) if (M.stat != DEAD) M.emote("scream") if(user) user.log_message("Cremated [M]/[M.ckey]", INDIVIDUAL_ATTACK_LOG) log_attack("\[[time_stamp()]\] [user]/[user.ckey] cremated [M]/[M.ckey]") else log_attack("\[[time_stamp()]\] UNKNOWN cremated [M]/[M.ckey]") M.death(1) if(M) //some animals get automatically deleted on death. M.ghostize() qdel(M) for(var/obj/O in conts) //obj instead of obj/item so that bodybags and ashes get destroyed. We dont want tons and tons of ash piling up if(O != connected) //Creamtorium does not burn hot enough to destroy the tray qdel(O) new /obj/effect/decal/cleanable/ash(src) sleep(30) if(!QDELETED(src)) locked = FALSE update_icon() playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //you horrible people /obj/structure/bodycontainer/crematorium/creamatorium name = "creamatorium" desc = "A human incinerator. Works well during ice cream socials." /obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user) var/list/icecreams = new() for(var/mob/living/i_scream in GetAllContents()) var/obj/item/reagent_containers/food/snacks/icecream/IC = new() IC.set_cone_type("waffle") IC.add_mob_flavor(i_scream) icecreams += IC . = ..() for(var/obj/IC in icecreams) IC.forceMove(src) /* * Generic Tray * Parent class for morguetray and crematoriumtray * For overriding only */ /obj/structure/tray icon = 'icons/obj/stationobjs.dmi' density = TRUE layer = BELOW_OBJ_LAYER var/obj/structure/bodycontainer/connected = null anchored = TRUE pass_flags = LETPASSTHROW max_integrity = 350 /obj/structure/tray/Destroy() if(connected) connected.connected = null connected.update_icon() connected = null return ..() /obj/structure/tray/deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/metal (loc, 2) qdel(src) /obj/structure/tray/attack_paw(mob/user) return src.attack_hand(user) /obj/structure/tray/attack_hand(mob/user) if (src.connected) connected.close() add_fingerprint(user) else to_chat(user, "That's not connected to anything!") /obj/structure/tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user) if(!ismovableatom(O) || O.anchored || !Adjacent(user) || !user.Adjacent(O) || O.loc == user) return if(!ismob(O)) if(!istype(O, /obj/structure/closet/body_bag)) return else var/mob/M = O if(M.buckled) return if(!ismob(user) || user.lying || user.incapacitated()) return O.loc = src.loc if (user != O) visible_message("[user] stuffs [O] into [src].") return /* * Crematorium tray */ /obj/structure/tray/c_tray name = "crematorium tray" desc = "Apply body before burning." icon_state = "cremat" /* * Morgue tray */ /obj/structure/tray/m_tray name = "morgue tray" desc = "Apply corpse before closing." icon_state = "morguet" /obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target) if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 if(locate(/obj/structure/table) in get_turf(mover)) return 1 else return 0 /obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller) . = !density if(ismovableatom(caller)) var/atom/movable/mover = caller . = . || mover.checkpass(PASSTABLE)