mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-30 04:02:33 +00:00
* amogus
* Revert "amogus"
This reverts commit ebaa99c77b.
* Part 1
* rest of the airlocks
holy shit that took a long time
* part 2
* part 3
finale
* conflict resolution
* fixes warnings
* fixes paneloen airlock emissives
* adds back changes from #18145
* #18085 sprites
* SteelSlayer Review
readded process in status_display, idk why I removed it, it broke some functionality
* future proofing firedoors
Talked with the contributor who added emissive appearances to the codebase. As of now they wont block them unless they spawn as closed, but with future PR merges this code will work.
* solar panel PR conflict resolve
* pain
* small fix
* farie82 suggestions
Co-authored-by: Farie82 <farie82@users.noreply.github.com>
* farie82 suggestions part 2
* farie82 suggestions part 3
* finalle
pog champ ers 2000
* farie82 suggestions the sequel
Co-authored-by: Farie82 <farie82@users.noreply.github.com>
* SteelSlayer Suggestions
Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>
Co-authored-by: Farie82 <farie82@users.noreply.github.com>
Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>
506 lines
12 KiB
Plaintext
506 lines
12 KiB
Plaintext
/* Morgue stuff
|
|
* Contains:
|
|
* Morgue
|
|
* Morgue trays
|
|
* Creamatorium
|
|
* Creamatorium trays
|
|
*/
|
|
|
|
/*
|
|
* Morgue
|
|
*/
|
|
|
|
#define EXTENDED_TRAY "extended"
|
|
#define EMPTY_MORGUE "empty"
|
|
#define UNREVIVABLE "unrevivable"
|
|
#define REVIVABLE "revivable"
|
|
#define NOT_BODY "notbody"
|
|
#define GHOST_CONNECTED "ghost"
|
|
|
|
/obj/structure/morgue
|
|
name = "morgue"
|
|
desc = "Used to keep bodies in until someone fetches them."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "morgue"
|
|
density = TRUE
|
|
max_integrity = 400
|
|
dir = EAST
|
|
var/obj/structure/m_tray/connected = null
|
|
var/static/status_descriptors = list(
|
|
EXTENDED_TRAY = "The tray is currently extended.",
|
|
EMPTY_MORGUE = "The tray is currently empty.",
|
|
UNREVIVABLE = "The tray contains an unviable body.",
|
|
REVIVABLE = "The tray contains a body that is responsive to revival techniques.",
|
|
NOT_BODY = "The tray contains something that is not a body.",
|
|
GHOST_CONNECTED = "The tray contains a body that might be responsive."
|
|
)
|
|
anchored = TRUE
|
|
var/open_sound = 'sound/items/deconstruct.ogg'
|
|
var/status
|
|
|
|
/obj/structure/morgue/Initialize()
|
|
. = ..()
|
|
update_icon(update_state())
|
|
set_light(1, LIGHTING_MINIMUM_POWER)
|
|
|
|
/obj/structure/morgue/proc/update_state()
|
|
. = UPDATE_OVERLAYS
|
|
if(connected)
|
|
status = EXTENDED_TRAY
|
|
return
|
|
if(!length(contents))
|
|
status = EMPTY_MORGUE
|
|
return
|
|
var/mob/living/M = locate() in contents
|
|
var/obj/structure/closet/body_bag/B = locate() in contents
|
|
if(!M)
|
|
M = locate() in B
|
|
if(!M)
|
|
status = NOT_BODY
|
|
return
|
|
var/mob/dead/observer/G = M.get_ghost()
|
|
if(M.mind && !M.mind.suicided)
|
|
if(M.client)
|
|
status = REVIVABLE
|
|
return
|
|
if(G && G.client) //There is a ghost and it is connected to the server
|
|
status = GHOST_CONNECTED
|
|
return
|
|
status = UNREVIVABLE
|
|
|
|
/obj/structure/morgue/update_overlays()
|
|
. = ..()
|
|
underlays.Cut()
|
|
if(!connected)
|
|
. += "morgue_[status]"
|
|
underlays += emissive_appearance(icon, "morgue_[status]")
|
|
if(name != initial(name))
|
|
. += "morgue_label"
|
|
|
|
/obj/structure/morgue/examine(mob/user)
|
|
. = ..()
|
|
. += "[status_descriptors[status]]"
|
|
|
|
/obj/structure/morgue/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
if(2.0)
|
|
if(prob(50))
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
if(3.0)
|
|
if(prob(5))
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
return
|
|
|
|
/obj/structure/morgue/attack_hand(mob/user as mob)
|
|
if(connected)
|
|
for(var/atom/movable/A in connected.loc)
|
|
if(!( A.anchored ))
|
|
A.forceMove(src)
|
|
playsound(loc, open_sound, 50, 1)
|
|
QDEL_NULL(connected)
|
|
else
|
|
playsound(loc, open_sound, 50, 1)
|
|
connect()
|
|
add_fingerprint(user)
|
|
update_icon(update_state())
|
|
return
|
|
|
|
/obj/structure/morgue/attackby(P as obj, mob/user as mob, params)
|
|
if(istype(P, /obj/item/pen))
|
|
var/t = rename_interactive(user, P)
|
|
if(isnull(t))
|
|
return
|
|
update_icon(UPDATE_OVERLAYS)
|
|
add_fingerprint(user)
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/morgue/wirecutter_act(mob/user)
|
|
if(name != initial(name))
|
|
to_chat(user, "<span class='notice'>You cut the tag off the morgue.</span>")
|
|
name = initial(name)
|
|
update_icon(UPDATE_OVERLAYS)
|
|
return TRUE
|
|
|
|
/obj/structure/morgue/relaymove(mob/user as mob)
|
|
if(user.stat)
|
|
return
|
|
connect()
|
|
|
|
/obj/structure/morgue/proc/connect()
|
|
connected = new /obj/structure/m_tray( loc )
|
|
step(connected, dir)
|
|
connected.layer = BELOW_OBJ_LAYER
|
|
var/turf/T = get_step(src, dir)
|
|
if(T.contents.Find(connected))
|
|
connected.connected = src
|
|
for(var/atom/movable/A in src)
|
|
if(A.move_resist != INFINITY)
|
|
A.forceMove(connected.loc)
|
|
connected.icon_state = "morgue_tray"
|
|
connected.dir = dir
|
|
else
|
|
QDEL_NULL(connected)
|
|
|
|
/obj/structure/morgue/Destroy()
|
|
if(!connected)
|
|
var/turf/T = loc
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(T)
|
|
else
|
|
QDEL_NULL(connected)
|
|
return ..()
|
|
|
|
/obj/structure/morgue/container_resist(mob/living/L)
|
|
var/mob/living/carbon/CM = L
|
|
if(!istype(CM))
|
|
return
|
|
if(CM.stat || CM.restrained())
|
|
return
|
|
|
|
to_chat(CM, "<span class='alert'>You attempt to slide yourself out of \the [src]...</span>")
|
|
src.attack_hand(CM)
|
|
|
|
|
|
/obj/structure/morgue/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 tray
|
|
*/
|
|
/obj/structure/m_tray
|
|
name = "morgue tray"
|
|
desc = "Apply corpse before closing. May float away in no-gravity."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "morgue_tray"
|
|
density = TRUE
|
|
layer = 2.0
|
|
var/obj/structure/morgue/connected = null
|
|
anchored = TRUE
|
|
pass_flags = LETPASSTHROW
|
|
max_integrity = 350
|
|
|
|
|
|
/obj/structure/m_tray/attack_hand(mob/user as mob)
|
|
if(connected)
|
|
for(var/atom/movable/A as mob|obj in loc)
|
|
if(!( A.anchored ))
|
|
A.forceMove(connected)
|
|
connected.connected = null
|
|
connected.update_icon(UPDATE_OVERLAYS)
|
|
add_fingerprint(user)
|
|
qdel(src)
|
|
return
|
|
return
|
|
|
|
/obj/structure/m_tray/MouseDrop_T(atom/movable/O, mob/living/user)
|
|
if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src) || user.contents.Find(O)))
|
|
return
|
|
if(!ismob(O) && !istype(O, /obj/structure/closet/body_bag))
|
|
return
|
|
if(!ismob(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
|
|
return
|
|
O.forceMove(loc)
|
|
if(user != O)
|
|
user.visible_message("<span class='warning'>[user] stuffs [O] into [src]!</span>")
|
|
return
|
|
|
|
/obj/structure/m_tray/Destroy()
|
|
if(connected && connected.connected == src)
|
|
connected.connected = null
|
|
connected = null
|
|
return ..()
|
|
|
|
/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target, height=0)
|
|
if(height == 0)
|
|
return 1
|
|
|
|
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(ismovable(caller))
|
|
var/atom/movable/mover = caller
|
|
. = . || mover.checkpass(PASSTABLE)
|
|
|
|
/*
|
|
* Crematorium
|
|
*/
|
|
|
|
/obj/structure/crematorium
|
|
name = "crematorium"
|
|
desc = "A human incinerator. Works well on barbeque nights."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "crema"
|
|
density = TRUE
|
|
var/obj/structure/c_tray/connected = null
|
|
anchored = TRUE
|
|
var/cremating = FALSE
|
|
var/id = 1
|
|
var/locked = FALSE
|
|
var/open_sound = 'sound/items/deconstruct.ogg'
|
|
|
|
/obj/structure/crematorium/Initialize(mapload)
|
|
. = ..()
|
|
update_icon(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/crematorium/update_overlays()
|
|
. = ..()
|
|
if(connected)
|
|
return
|
|
. += "crema_closed"
|
|
if(cremating)
|
|
. += "crema_active"
|
|
return
|
|
if(length(contents))
|
|
. += "crema_full"
|
|
|
|
/obj/structure/crematorium/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
if(2.0)
|
|
if(prob(50))
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
if(3.0)
|
|
if(prob(5))
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(loc)
|
|
ex_act(severity)
|
|
qdel(src)
|
|
return
|
|
return
|
|
|
|
/obj/structure/crematorium/attack_hand(mob/user as mob)
|
|
if(cremating)
|
|
to_chat(usr, "<span class='warning'>It's locked.</span>")
|
|
return
|
|
if(connected && !locked)
|
|
for(var/atom/movable/A in connected.loc)
|
|
if(!(A.anchored) && A.move_resist != INFINITY)
|
|
A.forceMove(src)
|
|
playsound(loc, open_sound, 50, 1)
|
|
QDEL_NULL(connected)
|
|
else if(!locked)
|
|
playsound(loc, open_sound, 50, 1)
|
|
connect()
|
|
add_fingerprint(user)
|
|
update_icon(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/crematorium/attackby(P as obj, mob/user as mob, params)
|
|
if(istype(P, /obj/item/pen))
|
|
rename_interactive(user, P)
|
|
add_fingerprint(user)
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/crematorium/relaymove(mob/user as mob)
|
|
if(user.stat || locked)
|
|
return
|
|
connect()
|
|
|
|
/obj/structure/crematorium/proc/connect()
|
|
connected = new /obj/structure/c_tray( loc )
|
|
step(connected, SOUTH)
|
|
connected.layer = BELOW_OBJ_LAYER
|
|
var/turf/T = get_step(src, SOUTH)
|
|
if(T.contents.Find(connected))
|
|
connected.connected = src
|
|
update_icon(UPDATE_OVERLAYS)
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(connected.loc)
|
|
connected.icon_state = "crema_tray"
|
|
else
|
|
QDEL_NULL(connected)
|
|
|
|
/obj/structure/crematorium/proc/cremate(mob/user as mob)
|
|
if(cremating)
|
|
return //don't let you cremate something twice or w/e
|
|
|
|
if(contents.len <= 0)
|
|
for(var/mob/M in viewers(src))
|
|
M.show_message("<span class='warning'>You hear a hollow crackle.</span>", 1)
|
|
return
|
|
|
|
else
|
|
for(var/mob/M in viewers(src))
|
|
M.show_message("<span class='warning'>You hear a roar as the crematorium activates.</span>", 1)
|
|
|
|
cremating = TRUE
|
|
locked = TRUE
|
|
update_icon(UPDATE_OVERLAYS)
|
|
|
|
for(var/mob/living/M in search_contents_for(/mob/living))
|
|
if(QDELETED(M))
|
|
continue
|
|
if(M.stat!=2)
|
|
M.emote("scream")
|
|
if(istype(user))
|
|
add_attack_logs(user, M, "Cremated")
|
|
M.death(1)
|
|
if(QDELETED(M))
|
|
continue // Re-check for mobs that delete themselves on death
|
|
M.ghostize()
|
|
qdel(M)
|
|
|
|
for(var/obj/O in contents) //obj instead of obj/item so that bodybags and ashes get destroyed. We dont want tons and tons of ash piling up
|
|
qdel(O)
|
|
|
|
new /obj/effect/decal/cleanable/ash(src)
|
|
sleep(30)
|
|
cremating = FALSE
|
|
locked = FALSE
|
|
update_icon(UPDATE_OVERLAYS)
|
|
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
|
|
return
|
|
|
|
/obj/structure/crematorium/Destroy()
|
|
if(!connected)
|
|
var/turf/T = loc
|
|
for(var/atom/movable/A in src)
|
|
A.forceMove(T)
|
|
else
|
|
QDEL_NULL(connected)
|
|
return ..()
|
|
|
|
/obj/structure/crematorium/container_resist(mob/living/L)
|
|
var/mob/living/carbon/CM = L
|
|
if(!istype(CM))
|
|
return
|
|
if(CM.stat || CM.restrained())
|
|
return
|
|
|
|
to_chat(CM, "<span class='alert'>You attempt to slide yourself out of \the [src]...</span>")
|
|
src.attack_hand(CM)
|
|
|
|
/obj/structure/crematorium/get_remote_view_fullscreens(mob/user)
|
|
if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
|
|
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 2)
|
|
|
|
/*
|
|
* Crematorium tray
|
|
*/
|
|
/obj/structure/c_tray
|
|
name = "crematorium tray"
|
|
desc = "Apply body before burning."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "crema_tray"
|
|
density = TRUE
|
|
layer = 2.0
|
|
var/obj/structure/crematorium/connected = null
|
|
anchored = TRUE
|
|
pass_flags = LETPASSTHROW
|
|
|
|
/obj/structure/c_tray/attack_hand(mob/user as mob)
|
|
if(connected)
|
|
for(var/atom/movable/A as mob|obj in loc)
|
|
if(!( A.anchored ))
|
|
A.forceMove(connected)
|
|
//Foreach goto(26)
|
|
connected.connected = null
|
|
connected.update_icon(UPDATE_OVERLAYS)
|
|
add_fingerprint(user)
|
|
qdel(src)
|
|
return
|
|
return
|
|
|
|
/obj/structure/c_tray/MouseDrop_T(atom/movable/O, mob/living/user)
|
|
if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src) || user.contents.Find(O)))
|
|
return
|
|
if(!ismob(O) && !istype(O, /obj/structure/closet/body_bag))
|
|
return
|
|
if(!ismob(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
|
|
return
|
|
O.forceMove(loc)
|
|
if(user != O)
|
|
user.visible_message("<span class='warning'>[user] stuffs [O] into [src]!</span>")
|
|
//Foreach goto(99)
|
|
return
|
|
|
|
/obj/structure/c_tray/Destroy()
|
|
if(connected && connected.connected == src)
|
|
connected.connected = null
|
|
connected = null
|
|
return ..()
|
|
|
|
// Crematorium switch
|
|
/obj/machinery/crema_switch
|
|
desc = "Burn baby burn!"
|
|
name = "crematorium igniter"
|
|
icon = 'icons/obj/power.dmi'
|
|
icon_state = "crema_switch"
|
|
power_channel = EQUIP
|
|
use_power = IDLE_POWER_USE
|
|
idle_power_usage = 100
|
|
active_power_usage = 5000
|
|
anchored = TRUE
|
|
req_access = list(ACCESS_CREMATORIUM)
|
|
var/on = FALSE
|
|
var/area/area = null
|
|
var/otherarea = null
|
|
var/id = 1
|
|
|
|
/obj/machinery/crema_switch/attack_ghost(mob/user)
|
|
if(user.can_advanced_admin_interact())
|
|
return attack_hand(user)
|
|
|
|
/obj/machinery/crema_switch/attack_hand(mob/user)
|
|
if(powered(power_channel)) // Do we have power?
|
|
if(allowed(usr) || user.can_advanced_admin_interact())
|
|
use_power(400000)
|
|
for(var/obj/structure/crematorium/C in world)
|
|
if(C.id == id)
|
|
if(!C.cremating)
|
|
C.cremate(user)
|
|
|
|
|
|
else
|
|
to_chat(usr, "<span class='warning'>Access denied.</span>")
|
|
|
|
/mob/proc/update_morgue()
|
|
if(stat == DEAD)
|
|
var/obj/structure/morgue/morgue
|
|
var/mob/living/C = src
|
|
var/mob/dead/observer/G = src
|
|
if(istype(G) && G.can_reenter_corpse && G.mind) //We're a ghost, let's find our corpse
|
|
C = G.mind.current
|
|
if(istype(C)) //We found our corpse, is it inside a morgue?
|
|
morgue = get(C.loc, /obj/structure/morgue)
|
|
if(morgue)
|
|
morgue.update_icon(UPDATE_OVERLAYS)
|
|
|
|
#undef EXTENDED_TRAY
|
|
#undef EMPTY_MORGUE
|
|
#undef UNREVIVABLE
|
|
#undef REVIVABLE
|
|
#undef NOT_BODY
|
|
#undef GHOST_CONNECTED
|