diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 51c4ce1b6a7e..48e0e794b374 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1534,6 +1534,8 @@ GLOBAL_LIST_EMPTY(icon_dimensions) GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height()) return GLOB.icon_dimensions[icon_path] +/// Strips all underlays on a different plane from an appearance. +/// Returns the stripped appearance. /proc/strip_appearance_underlays(mutable_appearance/appearance) var/base_plane = PLANE_TO_TRUE(appearance.plane) for(var/mutable_appearance/underlay as anything in appearance.underlays) @@ -1542,3 +1544,36 @@ GLOBAL_LIST_EMPTY(icon_dimensions) if(PLANE_TO_TRUE(underlay.plane) != base_plane) appearance.underlays -= underlay return appearance + +/** + * Copies the passed /appearance, returns a /mutable_appearance + * + * Filters out certain overlays from the copy, depending on their planes + * Prevents stuff like lighting from being copied to the new appearance + */ +/proc/copy_appearance_filter_overlays(appearance_to_copy) + var/mutable_appearance/copy = new(appearance_to_copy) + var/static/list/plane_whitelist = list(FLOAT_PLANE, GAME_PLANE, FLOOR_PLANE) + + /// Ideally we'd have knowledge what we're removing but i'd have to be done on target appearance retrieval + var/list/overlays_to_keep = list() + for(var/mutable_appearance/special_overlay as anything in copy.overlays) + if(isnull(special_overlay)) + continue + var/mutable_appearance/real = new() + real.appearance = special_overlay + if(PLANE_TO_TRUE(real.plane) in plane_whitelist) + overlays_to_keep += real + copy.overlays = overlays_to_keep + + var/list/underlays_to_keep = list() + for(var/mutable_appearance/special_underlay as anything in copy.underlays) + if(isnull(special_underlay)) + continue + var/mutable_appearance/real = new() + real.appearance = special_underlay + if(PLANE_TO_TRUE(real.plane) in plane_whitelist) + underlays_to_keep += real + copy.underlays = underlays_to_keep + + return copy diff --git a/monkestation/code/modules/datums/components/glitching_state.dm b/monkestation/code/modules/datums/components/glitching_state.dm index 36eaf967b5f7..0100a9c92658 100644 --- a/monkestation/code/modules/datums/components/glitching_state.dm +++ b/monkestation/code/modules/datums/components/glitching_state.dm @@ -1,13 +1,12 @@ /datum/component/glitching_state var/count = 5 - var/list/obj/effect/after_image/after_images + var/list/obj/effect/after_image/after_images = list() /datum/component/glitching_state/Initialize(count = 5) . = ..() var/atom/movable/movable = parent if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE - src.after_images = list() src.count = count if(count > 1) for(var/number = 1 to count) @@ -35,17 +34,21 @@ /datum/component/glitching_state/RegisterWithParent() . = ..() RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_dir_change)) + RegisterSignal(parent, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(do_sync)) /datum/component/glitching_state/UnregisterFromParent() . = ..() - UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE) + UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_LIVING_SET_BODY_POSITION)) /datum/component/glitching_state/process(seconds_per_tick) for(var/obj/effect/after_image/image as anything in after_images) image.sync_with_parent(parent, actual_loc = FALSE) -/datum/component/glitching_state/proc/on_dir_change(datum/source, old_dir, new_dir) +/datum/component/glitching_state/proc/on_dir_change(atom/movable/source, old_dir, new_dir) SIGNAL_HANDLER for(var/obj/effect/after_image/image as anything in after_images) image.sync_with_parent(parent, actual_loc = FALSE, dir_override = new_dir) +/datum/component/glitching_state/proc/do_sync(atom/movable/source) + SIGNAL_HANDLER + process() diff --git a/monkestation/code/modules/ranching/components/afterimage.dm b/monkestation/code/modules/ranching/components/afterimage.dm index 8e9d0f75e0d8..770baed7c9e7 100644 --- a/monkestation/code/modules/ranching/components/afterimage.dm +++ b/monkestation/code/modules/ranching/components/afterimage.dm @@ -86,14 +86,17 @@ qdel(targeted_image) /obj/effect/after_image - mouse_opacity = FALSE - anchored = 2 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + anchored = TRUE + flags_1 = parent_type::flags_1 | DEMO_IGNORE_1 var/finalized_alpha = 100 var/active = FALSE + var/last_appearance_ref /obj/effect/after_image/New(_loc, min_x = -3, max_x = 3, min_y = -3, max_y = 3, time_a = 0.5 SECONDS, time_b = 3 SECONDS, finalized_alpha = 100) . = ..() src.finalized_alpha = finalized_alpha + animate(src, pixel_x = 0, time = 1, loop = -1) var/count = rand(5, 10) for(var/number = 1 to count) var/time = time_a + rand() * time_b @@ -101,21 +104,27 @@ var/pixel_y = number == count ? 0 : rand(min_y, max_y) animate(time = time, easing = pick(LINEAR_EASING, SINE_EASING, CIRCULAR_EASING, CUBIC_EASING), pixel_x = pixel_x, pixel_y = pixel_y, loop = -1) +/obj/effect/after_image/Destroy() + last_appearance_ref = null + active = FALSE + return ..() + /obj/effect/after_image/proc/sync_with_parent(atom/movable/parent, loc_override = null, actual_loc = TRUE, dir_override = null) if(!active) return set_glide_size(parent.glide_size) - if(appearance != parent.appearance) - appearance = parent.appearance + var/parent_appearance_ref = ref(parent.appearance) + if(last_appearance_ref != parent_appearance_ref) + last_appearance_ref = parent_appearance_ref + appearance = copy_appearance_filter_overlays(parent.appearance) + name = "" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + transform = matrix() alpha = (alpha / 255.0) * finalized_alpha SET_PLANE_EXPLICIT(src, initial(parent.plane), parent) var/atom/target_loc = loc_override ? loc_override : parent.loc - if(target_loc != src.loc && actual_loc) + if(target_loc != loc && actual_loc) loc = target_loc var/target_dir = isnull(dir_override) ? parent.dir : dir_override if(dir != target_dir)//this is kinda important since otherwise it gets marked as demo dirty which is annoying setDir(target_dir) - -/obj/effect/after_image/Destroy() - active = FALSE - return ..()