mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
Fixes critical plane masters improperly not being readded in show_to (#72604) ## About The Pull Request [Adds support for pulling z offset context from an atom's plane](9f215c5316) This is needed to fix paper bins, since the object we plane set there isn't actually on a z level. Useful elsewhere too! [Fixes compiler errors that came from asserting that plane spokesmen had a plane var](b830002443) [Ensures lighting backdrops ALWAYS exist for each lighting plane.](0e931169f7) They can't float becuase we can see more then one plane at once yaknow? [Fixes parallax going to shit if a mob moved zs without having a client](244b2b25ba) Issue lies with how is_outside_bounds just blocked any plane readding It's possible for a client to not be connected during z moves, so we need to account for them rejoining in show_to, instead of just blocking any of our edge cases. Fixing this involved having parallax override blocks for show_plane and anything with the right critical flags ensuring mobs have JUST the right PMs and relays. It's duped logic but I'm unsure of how else to handle it and frankly this stuff is just kinda depressing. Might refactor later [show_to can be called twice successfully with no hide_from call.](092581a5c0) Ensures no runtimes off the registers from this ## Why It's Good For The Game Fixes #72543 Fixes lighting looking batshit on multiz. None reported this I cry into the night. ## Changelog 🆑 fix: Fixes parallax showing up ABOVE the game if you moved z levels while disconnected /🆑 --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: Time-Green <timkoster1@hotmail.com>
165 lines
6.1 KiB
Plaintext
165 lines
6.1 KiB
Plaintext
///A component that lets you turn an object invisible when you're standing on certain relative turfs to it, like behind a tree
|
|
/datum/component/seethrough
|
|
///List of lists that represent relative coordinates to the source atom
|
|
var/list/relative_turf_coords
|
|
///A list of turfs on which we make ourself transparent
|
|
var/list/watched_turfs
|
|
///Associate list, with client = trickery_image. Track which client is being tricked with which image
|
|
var/list/tricked_mobs = list()
|
|
|
|
///Which alpha do we animate towards?
|
|
var/target_alpha
|
|
///How long our fase in/out takes
|
|
var/animation_time
|
|
///After we somehow moved (because ss13 is godless and does not respect anything), how long do we need to stand still to feel safe to setup our "behind" area again
|
|
var/perimeter_reset_timer
|
|
///Does this object let clicks from players its transparent to pass through it
|
|
var/clickthrough
|
|
|
|
///see_through_map is a define pointing to a specific map. It's basically defining the area which is considered behind. See see_through_maps.dm for a list of maps
|
|
/datum/component/seethrough/Initialize(see_through_map = SEE_THROUGH_MAP_DEFAULT, target_alpha = 100, animation_time = 0.5 SECONDS, perimeter_reset_timer = 2 SECONDS, clickthrough = TRUE)
|
|
. = ..()
|
|
|
|
relative_turf_coords = GLOB.see_through_maps[see_through_map]
|
|
|
|
if(!isatom(parent) || !LAZYLEN(relative_turf_coords))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
relative_turf_coords = GLOB.see_through_maps[see_through_map]
|
|
src.relative_turf_coords = relative_turf_coords
|
|
src.target_alpha = target_alpha
|
|
src.animation_time = animation_time
|
|
src.perimeter_reset_timer = perimeter_reset_timer
|
|
src.clickthrough = clickthrough
|
|
|
|
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(dismantle_perimeter))
|
|
|
|
setup_perimeter(parent)
|
|
|
|
///Loop through a list with relative coordinate lists to mark those tiles and hide our parent when someone enters those tiles
|
|
/datum/component/seethrough/proc/setup_perimeter(atom/parent)
|
|
watched_turfs = list()
|
|
|
|
for(var/list/coordinates as anything in relative_turf_coords)
|
|
var/turf/target = TURF_FROM_COORDS_LIST(list(parent.x + coordinates[1], parent.y + coordinates[2], parent.z + coordinates[3]))
|
|
|
|
if(isnull(target))
|
|
continue
|
|
|
|
RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))
|
|
RegisterSignal(target, COMSIG_ATOM_EXITED, PROC_REF(on_exited))
|
|
|
|
watched_turfs.Add(target)
|
|
|
|
///Someone entered one of our tiles, so sent an override overlay and a cute animation to make us fade out a bit
|
|
/datum/component/seethrough/proc/on_entered(atom/source, atom/movable/entered)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!ismob(entered))
|
|
return
|
|
|
|
var/mob/mob = entered
|
|
|
|
if(!mob.client)
|
|
RegisterSignal(mob, COMSIG_MOB_LOGIN, PROC_REF(trick_mob))
|
|
return
|
|
|
|
if(mob in tricked_mobs)
|
|
return
|
|
|
|
trick_mob(mob)
|
|
|
|
///Remove the screen object and make us appear solid to the client again
|
|
/datum/component/seethrough/proc/on_exited(atom/source, atom/movable/exited, direction)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!ismob(exited))
|
|
return
|
|
|
|
var/mob/mob = exited
|
|
|
|
if(!mob.client)
|
|
UnregisterSignal(mob, COMSIG_MOB_LOGIN)
|
|
return
|
|
|
|
var/turf/moving_to = get_turf(exited)
|
|
if(moving_to in watched_turfs)
|
|
return
|
|
|
|
//Check if we're being 'tricked'
|
|
if(mob in tricked_mobs)
|
|
var/image/trickery_image = tricked_mobs[mob]
|
|
animate(trickery_image, alpha = 255, time = animation_time)
|
|
tricked_mobs.Remove(mob)
|
|
UnregisterSignal(mob, COMSIG_MOB_LOGOUT)
|
|
|
|
//after playing the fade-in animation, remove the screen obj
|
|
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/component/seethrough,clear_image), trickery_image, mob.client), animation_time)
|
|
|
|
///Apply the trickery image and animation
|
|
/datum/component/seethrough/proc/trick_mob(mob/fool)
|
|
var/datum/hud/our_hud = fool.hud_used
|
|
for(var/atom/movable/screen/plane_master/seethrough in our_hud.get_true_plane_masters(SEETHROUGH_PLANE))
|
|
seethrough.unhide_plane(fool)
|
|
|
|
var/atom/atom_parent = parent
|
|
var/image/user_overlay = new(atom_parent)
|
|
user_overlay.loc = atom_parent
|
|
user_overlay.override = TRUE
|
|
|
|
if(clickthrough)
|
|
//Special plane so we can click through the overlay
|
|
SET_PLANE_EXPLICIT(user_overlay, SEETHROUGH_PLANE, atom_parent)
|
|
|
|
//These are inherited, but we already use the atom's loc so we end up at double the pixel offset
|
|
user_overlay.pixel_x = 0
|
|
user_overlay.pixel_y = 0
|
|
|
|
fool.client.images += user_overlay
|
|
|
|
animate(user_overlay, alpha = target_alpha, time = animation_time)
|
|
|
|
tricked_mobs[fool] = user_overlay
|
|
RegisterSignal(fool, COMSIG_MOB_LOGOUT, PROC_REF(on_client_disconnect))
|
|
|
|
|
|
///Unrout ourselves after we somehow moved, and start a timer so we can re-restablish our behind area after standing still for a bit
|
|
/datum/component/seethrough/proc/dismantle_perimeter()
|
|
SIGNAL_HANDLER
|
|
|
|
for(var/turf in watched_turfs)
|
|
UnregisterSignal(turf, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED))
|
|
|
|
watched_turfs = null
|
|
clear_all_images()
|
|
|
|
//Timer override, so if our atom keeps moving the timer is reset until they stop for X time
|
|
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/component/seethrough,setup_perimeter), parent), perimeter_reset_timer, TIMER_OVERRIDE | TIMER_UNIQUE)
|
|
|
|
///Remove a screen image from a client
|
|
/datum/component/seethrough/proc/clear_image(image/removee, client/remove_from)
|
|
remove_from?.images -= removee //player could've logged out during the animation, so check just in case
|
|
|
|
/datum/component/seethrough/proc/clear_all_images()
|
|
for(var/mob/fool in tricked_mobs)
|
|
var/image/trickery_image = tricked_mobs[fool]
|
|
fool.client?.images -= trickery_image
|
|
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
|
|
var/datum/hud/our_hud = fool.hud_used
|
|
|
|
for(var/atom/movable/screen/plane_master/seethrough in our_hud.get_true_plane_masters(SEETHROUGH_PLANE))
|
|
seethrough.hide_plane(fool)
|
|
|
|
tricked_mobs.Cut()
|
|
|
|
///Image is removed when they log out because client gets deleted, so drop the mob reference
|
|
/datum/component/seethrough/proc/on_client_disconnect(mob/fool)
|
|
SIGNAL_HANDLER
|
|
|
|
tricked_mobs.Remove(fool)
|
|
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
|
|
RegisterSignal(fool, COMSIG_MOB_LOGIN, PROC_REF(trick_mob))
|
|
var/datum/hud/our_hud = fool.hud_used
|
|
for(var/atom/movable/screen/plane_master/seethrough in our_hud.get_true_plane_masters(SEETHROUGH_PLANE))
|
|
seethrough.hide_plane(fool)
|