Files
Aurora.3/code/modules/multiz/zmimic/mimic_movable.dm
BatrachophrenoandGitHub 9a496cb57b Openspace mimics stop lingering (#22344)
Fixes https://github.com/Aurorastation/Aurora.3/issues/22296

This appears to have been caused by an excessively long timer delay in
the destruction of the 'mimic' object created when an AM is viewable
from above through an openspace turf. Now, when transitioning up a
staircase or ladder to a higher z-level, mimics of yourself and any
objects you may have been pulling are no longer still visible for 10
seconds.

I do not know exactly why the original timer was set for so long.

I did not detect any performance issues or harddels when testing it
(knocking a bunch of random holes in the the 2nd floor of runtime and
setting a bunch of greimorians loose on the 1st floor so that their
openspace mimics would be continually created and destroyed.
2026-04-26 14:10:23 +00:00

189 lines
5.3 KiB
Plaintext

/atom/movable
/// The mimic (if any) that's *directly* copying us.
var/tmp/atom/movable/openspace/mimic/bound_overlay
/// If TRUE, this atom is ignored by Z-Mimic.
var/z_flags
/atom/movable/set_dir(ndir)
. = ..()
if (. && bound_overlay)
bound_overlay.set_dir(ndir)
/atom/movable/update_above()
if (!bound_overlay)
return
if (QDELETED(bound_overlay))
bound_overlay = null
return
if (!isturf(loc))
return
var/turf/T = loc
if (TURF_IS_MIMICING(T.above))
SSzcopy.queued_overlays += bound_overlay
bound_overlay.queued += 1
else
qdel(bound_overlay)
// Grabs a list of every openspace object that's directly or indirectly mimicing this object. Returns an empty list if none found.
/atom/movable/proc/get_above_oo()
. = list()
var/atom/movable/curr = src
while (curr.bound_overlay)
. += curr.bound_overlay
curr = curr.bound_overlay
// -- Openspace movables --
/atom/movable/openspace
name = ""
simulated = FALSE
anchored = TRUE
mouse_opacity = FALSE
/atom/movable/openspace/can_fall()
return FALSE
// No blowing up abstract objects.
/atom/movable/openspace/ex_act(ex_sev)
SHOULD_CALL_PARENT(FALSE)
return
/atom/movable/openspace/singularity_act()
return
/atom/movable/openspace/singularity_pull()
return
/atom/movable/openspace/singuloCanEat()
return
// -- MULTIPLIER / SHADOWER --
// Holder object used for dimming openspaces & copying lighting of below turf.
/atom/movable/openspace/multiplier
name = "openspace multiplier"
desc = DESC_PARENT
icon = 'icons/effects/lighting_overlay.dmi'
icon_state = "dark"
plane = OPEN_SPACE_PLANE_END
layer = MIMICED_LIGHTING_LAYER
// blend_mode = BLEND_MULTIPLY
color = "#00000033"
/atom/movable/openspace/multiplier/Destroy()
var/turf/myturf = loc
if (istype(myturf))
myturf.shadower = null
return ..()
// -- OPENSPACE OVERLAY --
// todo: rename
// Object used to hold a mimiced atom's appearance.
/atom/movable/openspace/mimic
plane = OPEN_SPACE_PLANE_END
var/atom/movable/associated_atom
var/depth
var/queued = FALSE
var/destruction_timer
var/mimiced_type
var/original_z
var/override_depth
var/have_performed_fixup = FALSE
/atom/movable/openspace/mimic/Initialize(mapload, ...)
. = ..()
SSzcopy.openspace_overlays += 1
/atom/movable/openspace/mimic/Destroy()
SSzcopy.openspace_overlays -= 1
if (associated_atom)
associated_atom.bound_overlay = null
associated_atom = null
queued = FALSE
if (destruction_timer)
deltimer(destruction_timer)
return ..()
/atom/movable/openspace/mimic/attackby(obj/item/attacking_item, mob/user)
to_chat(user, SPAN_NOTICE("\The [src] is too far away."))
/atom/movable/openspace/mimic/attack_hand(mob/user)
to_chat(user, SPAN_NOTICE("You cannot reach \the [src] from here."))
/atom/movable/openspace/mimic/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
SHOULD_CALL_PARENT(FALSE)
. = associated_atom.examine(arglist(args)) // just pass all the args to the copied atom
/atom/movable/openspace/mimic/forceMove(atom/destination)
. = ..()
if (TURF_IS_MIMICING(destination))
if (destruction_timer)
deltimer(destruction_timer)
destruction_timer = null
else if (!destruction_timer)
destruction_timer = addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, qdel_self)), 1, TIMER_STOPPABLE)
// Called when the turf we're on is deleted/changed.
/atom/movable/openspace/mimic/proc/owning_turf_changed()
if (!destruction_timer)
destruction_timer = addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, qdel_self)), 1, TIMER_STOPPABLE)
// -- TURF PROXY --
// This thing holds the mimic appearance for non-OVERWRITE turfs.
/atom/movable/openspace/turf_proxy
plane = OPEN_SPACE_PLANE_END
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
z_flags = ZMM_IGNORE // Only one of these should ever be visible at a time, the mimic logic will handle that.
/atom/movable/openspace/turf_proxy/attackby(obj/item/attacking_item, mob/user)
loc.attackby(attacking_item, user)
/atom/movable/openspace/turf_proxy/attack_hand(mob/user as mob)
loc.attack_hand(user)
/atom/movable/openspace/turf_proxy/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
loc.attack_generic(user)
/atom/movable/openspace/turf_proxy/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
SHOULD_CALL_PARENT(FALSE)
. = loc.examine(arglist(args))
// -- TURF MIMIC --
// A type for copying non-overwrite turfs' self-appearance.
/atom/movable/openspace/turf_mimic
plane = OPEN_SPACE_PLANE_END // These *should* only ever be at the top?
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/turf/delegate
/atom/movable/openspace/turf_mimic/Initialize(mapload, ...)
. = ..()
ASSERT(isturf(loc))
var/turf/T = loc
delegate = T.below
/atom/movable/openspace/turf_mimic/attackby(obj/item/attacking_item, mob/user)
loc.attackby(attacking_item, user)
/atom/movable/openspace/turf_mimic/attack_hand(mob/user as mob)
to_chat(user, SPAN_NOTICE("You cannot reach \the [src] from here."))
/atom/movable/openspace/turf_mimic/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
to_chat(user, SPAN_NOTICE("You cannot reach \the [src] from here."))
/atom/movable/openspace/turf_mimic/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
SHOULD_CALL_PARENT(FALSE)
. = delegate.examine(arglist(args))