Files
CHOMPStation2/code/modules/multiz/zshadow.dm
2021-05-05 18:45:31 +00:00

127 lines
3.2 KiB
Plaintext

/mob // TODO: rewrite as obj.
var/mob/zshadow/shadow
/mob/zshadow
plane = OVER_OPENSPACE_PLANE
name = "shadow"
desc = "Z-level shadow"
status_flags = GODMODE
anchored = 1
unacidable = 1
density = 0
opacity = 0 // Don't trigger lighting recalcs gah! TODO - consider multi-z lighting.
//auto_init = FALSE // We do not need to be initialize()d
var/mob/owner = null // What we are a shadow of.
/mob/zshadow/can_fall()
return FALSE
/mob/zshadow/New(var/mob/L)
if(!istype(L))
qdel(src)
return
owner = L
sync_icon(L)
/mob/zshadow/Destroy()
owner.shadow = null
owner = null
..() //But we don't return because the hint is wrong
return QDEL_HINT_QUEUE
/mob/Destroy()
QDEL_NULL(shadow)
. = ..()
/mob/zshadow/examine(mob/user, distance, infix, suffix)
if(!owner)
// The only time we should have a null owner is if we are in nullspace. Help figure out why we were examined.
crash_with("[src] ([type]) @ [log_info_line()] was examined by [user] @ [global.log_info_line(user)]")
return list()
return owner.examine(user, distance, infix, suffix)
// Relay some stuff they hear
/mob/zshadow/hear_say(var/list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(speaker && speaker.z != src.z)
return // Only relay speech on our acutal z, otherwise we might relay sounds that were themselves relayed up!
if(isliving(owner))
verb += " from above"
return owner.hear_say(message_pieces, verb, italics, speaker, speech_sound, sound_vol)
/mob/zshadow/proc/sync_icon(var/mob/M)
name = M.name
icon = M.icon
icon_state = M.icon_state
//color = M.color
color = "#848484"
overlays = M.overlays
transform = M.transform
dir = M.dir
invisibility = M.invisibility
if(shadow)
shadow.sync_icon(src)
/mob/living/Moved()
. = ..()
check_shadow()
/mob/living/forceMove()
. = ..()
check_shadow()
/mob/living/on_mob_jump()
// We're about to be admin-jumped.
// Unfortuantely loc isn't set until after this proc is called. So we must spawn() so check_shadow executes with the new loc.
. = ..()
if(shadow)
spawn(0)
check_shadow()
/mob/living/proc/check_shadow()
var/mob/M = src
if(isturf(M.loc))
var/turf/simulated/open/OS = GetAbove(src)
while(OS && istype(OS))
if(!M.shadow)
M.shadow = new /mob/zshadow(M)
M.shadow.forceMove(OS)
M = M.shadow
OS = GetAbove(M)
// The topmost level does not need a shadow!
if(M.shadow)
qdel(M.shadow)
M.shadow = null
//
// Handle cases where the owner mob might have changed its icon or overlays.
//
/mob/living/update_icons()
. = ..()
if(shadow)
shadow.sync_icon(src)
// WARNING - the true carbon/human/update_icons does not call ..(), therefore we must sideways override this.
// But be careful, we don't want to screw with that proc. So lets be cautious about what we do here.
/mob/living/carbon/human/update_icons()
. = ..()
if(shadow)
shadow.sync_icon(src)
/mob/set_dir(new_dir)
. = ..()
if(shadow)
shadow.set_dir(new_dir)
/mob/zshadow/set_typing_indicator(var/state)
if(!typing_indicator)
init_typing_indicator("typing")
if(state && !typing)
overlays += typing_indicator
typing = 1
else if(!state && typing)
overlays -= typing_indicator
typing = 0
if(shadow)
shadow.set_typing_indicator(state)