diff --git a/code/__DEFINES/dcs/signals/signals_plane_master_group.dm b/code/__DEFINES/dcs/signals/signals_plane_master_group.dm index d27adb5f8c9..61bd33c3e22 100644 --- a/code/__DEFINES/dcs/signals/signals_plane_master_group.dm +++ b/code/__DEFINES/dcs/signals/signals_plane_master_group.dm @@ -1,2 +1,2 @@ -/// from /datum/plane_master_group/proc/set_hud(): (datum/hud/new_hud) +/// from /datum/plane_master_group/proc/set_hud(): (datum/hud/old_hud, datum/hud/new_hud) #define COMSIG_GROUP_HUD_CHANGED "group_hud_changed" diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 1ae8403c644..6421cdee67a 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -47,6 +47,7 @@ #define PARALLAX_HIGH "High" #define PARALLAX_MED "Medium" #define PARALLAX_LOW "Low" +#define PARALLAX_BOOMER "Old" #define PARALLAX_DISABLE "Disabled" #define SCALING_METHOD_NORMAL "normal" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index c93cb22246a..8365b5a58ed 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -52,6 +52,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai // Hud traits /// This hud is owned by a client with an open escape menu #define TRAIT_ESCAPE_MENU_OPEN "escape_menu_open" +/// This hud has parallax displayed on it +#define TRAIT_PARALLAX_DISPLAYED "parallax_displayed" // Mob traits /// Forces the user to stay unconscious. diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 6fffe7203f4..8f46c495437 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -144,6 +144,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( ), /datum/hud = list( "TRAIT_ESCAPE_MENU_OPEN" = TRAIT_ESCAPE_MENU_OPEN, + "TRAIT_PARALLAX_DISPLAYED" = TRAIT_PARALLAX_DISPLAYED, ), /datum/wound = list( "TRAIT_WOUND_SCANNED" = TRAIT_WOUND_SCANNED, diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index b4b4bc0af17..6af2635972b 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -393,7 +393,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( screenmob.reload_fullscreen() if(screenmob == mymob) - update_parallax_pref(screenmob) + update_parallax_pref() else viewmob.hud_used.update_parallax_pref() diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm index 9ed21d8e073..eaebdbfcaf5 100644 --- a/code/_onclick/hud/parallax/parallax.dm +++ b/code/_onclick/hud/parallax/parallax.dm @@ -1,117 +1,76 @@ +/// Decides if parallax should be rendered or not, and sets things up accordingly +/datum/hud/proc/check_parallax() + var/client/displaying_client = mymob.client + if(isnull(displaying_client.parallax_rock)) + displaying_client.parallax_rock = new(null, null, displaying_client) -/datum/hud/proc/create_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client + /// Applies our preferences to our existing display + apply_parallax_pref() + var/atom/movable/screen/parallax_home/rock = displaying_client?.parallax_rock - if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref - for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) - parallax.hide_plane(screenmob) - return + // Because other parts of the code can just REMOVE US FROM THE SCREEN for no reason as a joke + if (rock.displaying_layers) + ADD_TRAIT(src, TRAIT_PARALLAX_DISPLAYED, TRAIT_GENERIC) + displaying_client.screen |= rock + else + REMOVE_TRAIT(src, TRAIT_PARALLAX_DISPLAYED, TRAIT_GENERIC) + displaying_client.screen -= rock - for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) - parallax.unhide_plane(screenmob) - - if(isnull(C.parallax_rock)) - C.parallax_rock = new(null, src) - C.screen |= C.parallax_rock - - if(!length(C.parallax_layers_cached)) - C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) - if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) - - C.parallax_layers = C.parallax_layers_cached.Copy() - - if (length(C.parallax_layers) > C.parallax_layers_max) - C.parallax_layers.len = C.parallax_layers_max - - C.parallax_rock.vis_contents = C.parallax_layers - // We could do not do parallax for anything except the main plane group - // This could be changed, but it would require refactoring this whole thing - // And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :( - for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += plane_master - // this color makes parallax not black - plane_master.color = list( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 1, 1, 1, 1, - 0, 0, 0, 0 - ) - -/datum/hud/proc/remove_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - C.screen -= (C.parallax_rock) - for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += plane_master - plane_master.color = initial(plane_master.color) - C.parallax_layers = null - -/datum/hud/proc/apply_parallax_pref(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/turf/screen_location = get_turf(screenmob) +/datum/hud/proc/apply_parallax_pref() + var/turf/screen_location = get_turf(mymob) + var/client/displaying_client = mymob.client + var/atom/movable/screen/parallax_home/rock = displaying_client.parallax_rock if(SSmapping.level_trait(screen_location?.z, ZTRAIT_NOPARALLAX)) - return FALSE + rock.set_layer_settings(layers_to_draw = 0, draw_old_space = FALSE, animate_parallax = FALSE) + return - if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(viewmob, TRAIT_BYPASS_MEASURES)) - return FALSE + if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(mymob, TRAIT_BYPASS_MEASURES)) + rock.set_layer_settings(layers_to_draw = 0, draw_old_space = FALSE, animate_parallax = FALSE) + return - var/client/C = screenmob.client // Default to HIGH - var/parallax_selection = C?.prefs.read_preference(/datum/preference/choiced/parallax) || PARALLAX_HIGH + var/parallax_selection = displaying_client?.prefs.read_preference(/datum/preference/choiced/parallax) || PARALLAX_HIGH switch(parallax_selection) if (PARALLAX_INSANE) - C.parallax_layers_max = 5 - C.do_parallax_animations = TRUE - return TRUE + rock.set_layer_settings(layers_to_draw = 5, draw_old_space = FALSE, animate_parallax = TRUE) + return if(PARALLAX_HIGH) - C.parallax_layers_max = 4 - C.do_parallax_animations = TRUE - return TRUE + rock.set_layer_settings(layers_to_draw = 4, draw_old_space = FALSE, animate_parallax = TRUE) + return if (PARALLAX_MED) - C.parallax_layers_max = 3 - C.do_parallax_animations = TRUE - return TRUE + rock.set_layer_settings(layers_to_draw = 3, draw_old_space = FALSE, animate_parallax = TRUE) + return if (PARALLAX_LOW) - C.parallax_layers_max = 1 - C.do_parallax_animations = FALSE - return TRUE + rock.set_layer_settings(layers_to_draw = 1, draw_old_space = FALSE, animate_parallax = FALSE) + return + + if (PARALLAX_BOOMER) + rock.set_layer_settings(layers_to_draw = 0, draw_old_space = TRUE, animate_parallax = TRUE) + return if (PARALLAX_DISABLE) - return FALSE + rock.set_layer_settings(layers_to_draw = 0, draw_old_space = FALSE, animate_parallax = FALSE) + return -/datum/hud/proc/update_parallax_pref(mob/viewmob) - var/mob/screen_mob = viewmob || mymob - if(!screen_mob.client) +/datum/hud/proc/update_parallax_pref() + if(!mymob.client) return - remove_parallax(screen_mob) - create_parallax(screen_mob) - update_parallax(screen_mob) + check_parallax() + update_parallax() // This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = NONE, skip_windups, mob/viewmob) +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = NONE, skip_windups) . = FALSE - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - if(new_parallax_movedir == C.parallax_movedir) + var/client/displaying_client = mymob.client + if(new_parallax_movedir == displaying_client.parallax_movedir) return - var/animation_dir = new_parallax_movedir || C.parallax_movedir + var/animation_dir = new_parallax_movedir || displaying_client.parallax_movedir var/matrix/new_transform switch(animation_dir) if(NORTH) @@ -124,17 +83,17 @@ new_transform = matrix(1, 0,-480, 0, 1, 0) var/longest_timer = 0 - for(var/key in C.parallax_animate_timers) - deltimer(C.parallax_animate_timers[key]) - C.parallax_animate_timers = list() - for(var/atom/movable/screen/parallax_layer/layer as anything in C.parallax_layers) + for(var/key in displaying_client.parallax_animate_timers) + deltimer(displaying_client.parallax_animate_timers[key]) + displaying_client.parallax_animate_timers = list() + for(var/atom/movable/screen/parallax_layer/layer as anything in displaying_client.parallax_rock.parallax_layers) var/scaled_time = PARALLAX_LOOP_TIME / layer.speed if(new_parallax_movedir == NONE) // If we're stopping, we need to stop on the same dime, yeah? scaled_time = PARALLAX_LOOP_TIME longest_timer = max(longest_timer, scaled_time) if(skip_windups) - update_parallax_motionblur(C, layer, new_parallax_movedir, new_transform) + update_parallax_motionblur(displaying_client, layer, new_parallax_movedir, new_transform) continue layer.transform = new_transform @@ -144,15 +103,15 @@ //queue up another animate so lag doesn't create a shutter animate(transform = new_transform, time = 0) animate(transform = matrix(), time = scaled_time / 2) - C.parallax_animate_timers[layer] = addtimer(CALLBACK(src, PROC_REF(update_parallax_motionblur), C, layer, new_parallax_movedir, new_transform), scaled_time, TIMER_CLIENT_TIME|TIMER_STOPPABLE) + displaying_client.parallax_animate_timers[layer] = addtimer(CALLBACK(src, PROC_REF(update_parallax_motionblur), displaying_client, layer, new_parallax_movedir, new_transform), scaled_time, TIMER_CLIENT_TIME|TIMER_STOPPABLE) - C.dont_animate_parallax = world.time + min(longest_timer, PARALLAX_LOOP_TIME) - C.parallax_movedir = new_parallax_movedir + displaying_client.dont_animate_parallax = world.time + min(longest_timer, PARALLAX_LOOP_TIME) + displaying_client.parallax_movedir = new_parallax_movedir -/datum/hud/proc/update_parallax_motionblur(client/C, atom/movable/screen/parallax_layer/layer, new_parallax_movedir, matrix/new_transform) - if(!C) +/datum/hud/proc/update_parallax_motionblur(client/displaying_client, atom/movable/screen/parallax_layer/layer, new_parallax_movedir, matrix/new_transform) + if(!displaying_client) return - C.parallax_animate_timers -= layer + displaying_client.parallax_animate_timers -= layer // If we are moving in a direction, we used the QUAD_EASING function with EASE_IN // This means our position function is x^2. This is always LESS then the linear we're using here @@ -164,33 +123,34 @@ animate(layer, transform = new_transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) animate(transform = matrix(), time = scaled_time) -/datum/hud/proc/update_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - var/turf/posobj = get_turf(C.eye) +/datum/hud/proc/update_parallax() + var/client/displaying_client = mymob.client + var/turf/posobj = get_turf(displaying_client.eye) if(!posobj) return var/area/areaobj = posobj.loc // Update the movement direction of the parallax if necessary (for shuttles) - set_parallax_movedir(areaobj.parallax_movedir, FALSE, screenmob) + set_parallax_movedir(areaobj.parallax_movedir, FALSE, mymob) - if(!C.previous_turf || (C.previous_turf.z != posobj.z)) - C.previous_turf = posobj + if(!displaying_client.previous_turf || (displaying_client.previous_turf.z != posobj.z)) + displaying_client.previous_turf = posobj //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. - var/offset_x = posobj.x - C.previous_turf.x - var/offset_y = posobj.y - C.previous_turf.y + var/offset_x = posobj.x - displaying_client.previous_turf.x + var/offset_y = posobj.y - displaying_client.previous_turf.y - var/glide_rate = round(ICON_SIZE_ALL / screenmob.glide_size * world.tick_lag, world.tick_lag) - C.previous_turf = posobj + var/glide_rate = round(ICON_SIZE_ALL / mymob.glide_size * world.tick_lag, world.tick_lag) + displaying_client.previous_turf = posobj var/largest_change = max(abs(offset_x), abs(offset_y)) var/max_allowed_dist = (glide_rate / world.tick_lag) + 1 - // If we aren't already moving/don't allow parallax, have made some movement, and that movement was smaller then our "glide" size, animate - var/run_parralax = (C.do_parallax_animations && glide_rate && !areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && largest_change <= max_allowed_dist) + var/atom/movable/screen/parallax_home/rock = displaying_client.parallax_rock - for(var/atom/movable/screen/parallax_layer/parallax_layer as anything in C.parallax_layers) + // If we aren't already moving/don't allow parallax, have made some movement, and that movement was smaller then our "glide" size, animate + var/run_parralax = (rock.animate_parallax && glide_rate && !areaobj.parallax_movedir && displaying_client.dont_animate_parallax <= world.time && largest_change <= max_allowed_dist) + + for(var/atom/movable/screen/parallax_layer/parallax_layer as anything in rock.parallax_layers) var/our_speed = parallax_layer.speed var/change_x var/change_y @@ -232,15 +192,15 @@ /atom/movable/proc/update_parallax_contents() for(var/mob/client_mob as anything in client_mobs_in_contents) - if(length(client_mob?.client?.parallax_layers) && client_mob.hud_used) + if(client_mob?.client?.parallax_rock?.displaying_layers && client_mob.hud_used) client_mob.hud_used.update_parallax() /mob/proc/update_parallax_teleport() //used for arrivals shuttle - if(client?.eye && hud_used && length(client.parallax_layers)) + if(client?.eye && hud_used && client?.parallax_rock?.displaying_layers) var/area/areaobj = get_area(client.eye) hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) -// Root object for parallax, all parallax layers are drawn onto this +// Root object for parallax, all parallax layers are drawn onto this and it manages them INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_home) /atom/movable/screen/parallax_home icon = null @@ -248,6 +208,87 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_home) plane = PLANE_SPACE_PARALLAX screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /// Layers we are currently displaying + var/list/atom/movable/screen/parallax_layer/parallax_layers = list() + /// Pallet of layers we CAN display if we choose to, depending on our client's prefs + /// ensures quick removal/reinsertion doesn't cause cycling qdels + var/list/atom/movable/screen/parallax_layer/parallax_layers_cached = list() + /// How many normal space layers we want to draw, in increasing order of "depth" + var/layers_to_draw = 0 + /// If we want to draw the old space layer + var/draw_old_space = FALSE + /// Are we currently displaying any layers? + var/displaying_layers = FALSE + /// Are we animating parallax? + var/animate_parallax = FALSE + /// The client that owns us + var/client/owner + +/atom/movable/screen/parallax_home/Initialize(mapload, datum/hud/hud_owner, client/owner) + . = ..() + src.owner = owner + +/atom/movable/screen/parallax_home/Destroy() + clear_layers() + owner = null + return ..() + +/atom/movable/screen/parallax_home/proc/display_layers() + if(displaying_layers || length(parallax_layers_cached) == 0) + return + parallax_layers = parallax_layers_cached + vis_contents = parallax_layers_cached + displaying_layers = TRUE + +/atom/movable/screen/parallax_home/proc/hide_layers() + if(!displaying_layers) + return + parallax_layers = list() + vis_contents = list() + displaying_layers = FALSE + +/atom/movable/screen/parallax_home/proc/set_layer_settings(layers_to_draw, draw_old_space, animate_parallax) + src.animate_parallax = animate_parallax + if(src.layers_to_draw == layers_to_draw && src.draw_old_space == draw_old_space) + return + src.layers_to_draw = layers_to_draw + src.draw_old_space = draw_old_space + regenerate_layers() + +/atom/movable/screen/parallax_home/proc/generate_space_layer(index) + switch(index) + if(1) + return new /atom/movable/screen/parallax_layer/layer_1(null, null, owner) + if(2) + return new /atom/movable/screen/parallax_layer/layer_2(null, null, owner) + if(3) + return new /atom/movable/screen/parallax_layer/planet(null, null, owner) + if(4) + if(SSparallax.random_layer) + return new SSparallax.random_layer.type(null, null, owner, FALSE, SSparallax.random_layer) + else + return new /atom/movable/screen/parallax_layer/layer_3(null, null, owner) + if(5) + if(SSparallax.random_layer) + return new /atom/movable/screen/parallax_layer/layer_3(null, null, owner) + +/atom/movable/screen/parallax_home/proc/regenerate_layers() + clear_layers() + if(layers_to_draw == 0 && !draw_old_space) + return + + parallax_layers_cached = list() + for(var/space_layer in 1 to layers_to_draw) + parallax_layers_cached += generate_space_layer(space_layer) + + if(draw_old_space) + parallax_layers_cached += new /atom/movable/screen/parallax_layer/old(null, null, owner) + + display_layers() + +/atom/movable/screen/parallax_home/proc/clear_layers() + hide_layers() + QDEL_LIST(parallax_layers_cached) // We need parallax to always pass its args down into initialize, so we immediate init it INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) @@ -261,8 +302,10 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) blend_mode = BLEND_ADD plane = PLANE_SPACE_PARALLAX mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /// View size we're being rendered with + var/working_view = "" -/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE) +/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, client/owner, template = FALSE) . = ..() // Parallax layers are independent of hud, they care about client // Not doing this will just create a bunch of hard deletes @@ -271,42 +314,48 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) if(template) return - var/client/boss = hud_owner?.mymob?.canon_client - - if(!boss) // If this typepath all starts to harddel your culprit is likely this + if(!owner) // If this typepath all starts to harddel your culprit is likely this return INITIALIZE_HINT_QDEL // I do not want to know bestie - var/view = boss.view || world.view + var/view = owner.view || world.view update_o(view) - RegisterSignal(boss, COMSIG_VIEW_SET, PROC_REF(on_view_change)) + RegisterSignal(owner, COMSIG_VIEW_SET, PROC_REF(on_view_change)) /atom/movable/screen/parallax_layer/proc/on_view_change(datum/source, new_size) SIGNAL_HANDLER update_o(new_size) -/atom/movable/screen/parallax_layer/proc/update_o(view) - if (!view) - view = world.view - var/static/pixel_grid_size = ICON_SIZE_ALL * 15 - var/static/parallax_scaler = ICON_SIZE_ALL / pixel_grid_size +/atom/movable/screen/parallax_layer/proc/update_o(new_view) + if(working_view == new_view) + return + working_view = new_view + update_appearance() + +/atom/movable/screen/parallax_layer/update_overlays() + . = ..() + var/overlay_view = working_view + if (!overlay_view) + overlay_view = world.view + var/pixel_grid_size = ICON_SIZE_ALL * 15 + var/parallax_scaler = ICON_SIZE_ALL / pixel_grid_size // Turn the view size into a grid of correctly scaled overlays - var/list/viewscales = getviewsize(view) + var/list/viewscales = getviewsize(overlay_view) // This could be half the size but we need to provide space for parallax movement on mob movement, and movement on scroll from shuttles, so like this instead var/countx = (CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1) var/county = (CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1) - var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) if(x == 0 && y == 0) continue - var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) + var/mutable_appearance/texture_overlay = tileable_appearance() texture_overlay.pixel_w += pixel_grid_size * x texture_overlay.pixel_z += pixel_grid_size * y - new_overlays += texture_overlay - cut_overlays() - add_overlay(new_overlays) + . += texture_overlay + +/atom/movable/screen/parallax_layer/proc/tileable_appearance() + return mutable_appearance(icon, icon_state) /atom/movable/screen/parallax_layer/layer_1 icon_state = "layer1" @@ -323,6 +372,34 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 1.4 layer = 3 +/atom/movable/screen/parallax_layer/old + icon = null + icon_state = null // dog there's gonna be so many overlays... + speed = 0.6 + layer = 1 // Draws on its own + +/atom/movable/screen/parallax_layer/old/tileable_appearance() + var/mutable_appearance/copy = mutable_appearance(null, "") + // We have to use render targets to draw one of these flat and reuse it for this because FOR SOME REASON + // 16 (tile count) * (14 (animated state count) * 4 (frame count) + 1 (1 is not animated)) 480x480 states + // is TOO MUCH for the client. Whatever, see if I care. + copy.render_source = "*old_space_parallax" + return copy + +/atom/movable/screen/parallax_layer/old/update_overlays() + . = ..() + var/mutable_appearance/relayed_overlay = mutable_appearance('icons/effects/old_parallax.dmi', "1", appearance_flags = RESET_TRANSFORM|PIXEL_SCALE|KEEP_TOGETHER|KEEP_APART) + var/list/old_states = list("19", "21", "23", "24", "26", "29", "30", "31", "34", "35", "36", "37", "43", "46") + var/list/holder_overlays = list() + for(var/state in old_states) + holder_overlays += mutable_appearance('icons/effects/old_parallax.dmi', state) + relayed_overlay.overlays = holder_overlays + relayed_overlay.render_target = "*old_space_parallax" + // Renders the like, "input" appearance we draw to everything else + . += relayed_overlay + // The 0,0 appearance, can't reuse relayed_overlay for this because otherwise transforms would stack + . += tileable_appearance() + /atom/movable/screen/parallax_layer/planet icon_state = "planet" blend_mode = BLEND_OVERLAY @@ -330,17 +407,16 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 -/atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) +/atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner, client/owner) . = ..() - var/client/boss = hud_owner?.mymob?.canon_client - if(!boss) + if(!owner) return var/static/list/connections = list( COMSIG_MOVABLE_Z_CHANGED = PROC_REF(on_z_change), COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout), ) - AddComponent(/datum/component/connect_mob_behalf, boss, connections) - on_z_change(hud_owner?.mymob) + AddComponent(/datum/component/connect_mob_behalf, owner, connections) + on_z_change(owner.mob) /atom/movable/screen/parallax_layer/planet/proc/on_mob_logout(mob/source) SIGNAL_HANDLER diff --git a/code/_onclick/hud/parallax/random_layer.dm b/code/_onclick/hud/parallax/random_layer.dm index 379c0cbe2d9..51cf69a92c0 100644 --- a/code/_onclick/hud/parallax/random_layer.dm +++ b/code/_onclick/hud/parallax/random_layer.dm @@ -4,7 +4,7 @@ speed = 2 layer = 3 -/atom/movable/screen/parallax_layer/random/Initialize(mapload, datum/hud/hud_owner, template, atom/movable/screen/parallax_layer/random/twin) +/atom/movable/screen/parallax_layer/random/Initialize(mapload, datum/hud/hud_owner, client/owner, template, atom/movable/screen/parallax_layer/random/twin) . = ..() if(twin) diff --git a/code/_onclick/hud/rendering/plane_master_group.dm b/code/_onclick/hud/rendering/plane_master_group.dm index 433fb715836..17a7e1b8d26 100644 --- a/code/_onclick/hud/rendering/plane_master_group.dm +++ b/code/_onclick/hud/rendering/plane_master_group.dm @@ -34,12 +34,13 @@ if(our_hud) our_hud.master_groups -= key hide_hud() + var/datum/hud/old_hud = our_hud our_hud = new_hud if(new_hud) our_hud.master_groups[key] = src show_hud() build_planes_offset(our_hud, active_offset) - SEND_SIGNAL(src, COMSIG_GROUP_HUD_CHANGED, our_hud) + SEND_SIGNAL(src, COMSIG_GROUP_HUD_CHANGED, old_hud, our_hud) /// Display a plane master group to some viewer, so show all our planes to it /datum/plane_master_group/proc/attach_to(datum/hud/viewing_hud) diff --git a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm index 0599f56df34..36fd9f37d2d 100644 --- a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm +++ b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm @@ -67,6 +67,36 @@ . = ..() add_relay_to(GET_NEW_PLANE(RENDER_PLANE_EMISSIVE, offset), relay_layer = EMISSIVE_SPACE_LAYER) +/atom/movable/screen/plane_master/parallax_white/set_home(datum/plane_master_group/home) + . = ..() + if(home) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + hud_changed(null, null, home.our_hud) + +/atom/movable/screen/plane_master/parallax_white/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + if(old_hud) + UnregisterSignal(old_hud, list(SIGNAL_ADDTRAIT(TRAIT_PARALLAX_DISPLAYED), SIGNAL_REMOVETRAIT(TRAIT_PARALLAX_DISPLAYED)), PROC_REF(parallax_updated)) + if(new_hud) + RegisterSignals(new_hud, list(SIGNAL_ADDTRAIT(TRAIT_PARALLAX_DISPLAYED), SIGNAL_REMOVETRAIT(TRAIT_PARALLAX_DISPLAYED)), PROC_REF(parallax_updated)) + parallax_updated(new_hud) + +/atom/movable/screen/plane_master/parallax_white/proc/parallax_updated(datum/source) + SIGNAL_HANDLER + if(isnull(home.our_hud?.mymob)) + return + if(HAS_TRAIT(home.our_hud, TRAIT_PARALLAX_DISPLAYED)) + // Gives parallax a fullwhite backdrop to multiply against + color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) + else + color = initial(color) + ///Contains space parallax /atom/movable/screen/plane_master/parallax name = "Parallax" @@ -92,6 +122,29 @@ narsie_start_midway(GLOB.narsie_effect_last_modified) // We assume we're on the start, so we can use this number offset_increase(0, SSmapping.max_plane_offset) +/atom/movable/screen/plane_master/parallax/set_home(datum/plane_master_group/home) + . = ..() + if(home) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + hud_changed(null, null, home.our_hud) + +/atom/movable/screen/plane_master/parallax/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + if(old_hud) + UnregisterSignal(old_hud, list(SIGNAL_ADDTRAIT(TRAIT_PARALLAX_DISPLAYED), SIGNAL_REMOVETRAIT(TRAIT_PARALLAX_DISPLAYED)), PROC_REF(parallax_updated)) + if(new_hud) + RegisterSignals(new_hud, list(SIGNAL_ADDTRAIT(TRAIT_PARALLAX_DISPLAYED), SIGNAL_REMOVETRAIT(TRAIT_PARALLAX_DISPLAYED)), PROC_REF(parallax_updated)) + parallax_updated(new_hud) + +/atom/movable/screen/plane_master/parallax/proc/parallax_updated(datum/source) + SIGNAL_HANDLER + if(isnull(home.our_hud?.mymob)) + return + if(HAS_TRAIT(home.our_hud, TRAIT_PARALLAX_DISPLAYED)) + show_to(home.our_hud.mymob) + else + hide_from(home.our_hud.mymob) + /atom/movable/screen/plane_master/parallax/proc/on_offset_increase(datum/source, old_offset, new_offset) SIGNAL_HANDLER offset_increase(old_offset, new_offset) @@ -401,19 +454,19 @@ plane = CAMERA_STATIC_PLANE render_relay_planes = list(RENDER_PLANE_GAME) -/atom/movable/screen/plane_master/camera_static/show_to(mob/mymob) +/atom/movable/screen/plane_master/camera_static/set_home(datum/plane_master_group/home) . = ..() - if(!.) - return - var/datum/hud/our_hud = home.our_hud - if(isnull(our_hud)) - return + if(home) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + hud_changed(null, null, home.our_hud) - // We'll hide the slate if we're not seeing through a camera eye - // This can call on a cycle cause we don't clear in hide_from - // Yes this is the best way of hooking into the hud, I hate myself too - RegisterSignal(our_hud, COMSIG_HUD_EYE_CHANGED, PROC_REF(eye_changed), override = TRUE) - eye_changed(our_hud, null, our_hud.mymob?.canon_client?.eye) +/atom/movable/screen/plane_master/camera_static/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + if(old_hud) + UnregisterSignal(old_hud, COMSIG_HUD_EYE_CHANGED, PROC_REF(eye_changed)) + if(new_hud) + RegisterSignal(new_hud, COMSIG_HUD_EYE_CHANGED, PROC_REF(eye_changed)) + eye_changed(new_hud, null, new_hud.mymob?.canon_client?.eye) /atom/movable/screen/plane_master/camera_static/proc/eye_changed(datum/hud/source, atom/old_eye, atom/new_eye) SIGNAL_HANDLER diff --git a/code/_onclick/hud/rendering/render_plate.dm b/code/_onclick/hud/rendering/render_plate.dm index 4572b66e040..6286dfe3076 100644 --- a/code/_onclick/hud/rendering/render_plate.dm +++ b/code/_onclick/hud/rendering/render_plate.dm @@ -202,6 +202,12 @@ add_filter("emissives", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(EMISSIVE_RENDER_TARGET, offset), flags = MASK_INVERSE)) set_light_cutoff(10) +/atom/movable/screen/plane_master/rendering_plate/lighting/set_home(datum/plane_master_group/home) + . = ..() + if(home) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + hud_changed(null, null, home.our_hud) + /atom/movable/screen/plane_master/rendering_plate/lighting/show_to(mob/mymob) . = ..() if(!.) @@ -217,23 +223,20 @@ backdrop = mymob.overlay_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) - // Sorry, this is a bit annoying - // Basically, we only want the lighting plane we can actually see to attempt to render - // If we don't our lower plane gets totally overriden by the black void of the upper plane - var/datum/hud/hud = home.our_hud - // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this - if(hud) - RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) - offset_change(hud?.current_plane_offset || 0) set_light_cutoff(mymob.lighting_cutoff, mymob.lighting_color_cutoffs) /atom/movable/screen/plane_master/rendering_plate/lighting/hide_from(mob/oldmob) . = ..() oldmob.clear_fullscreen("lighting_backdrop_lit_[home.key]#[offset]") oldmob.clear_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]") - var/datum/hud/hud = home.our_hud - if(hud) - UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + if(old_hud) + UnregisterSignal(old_hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + if(new_hud) + RegisterSignal(new_hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + offset_change(new_hud?.current_plane_offset || 0) /atom/movable/screen/plane_master/rendering_plate/lighting/proc/on_offset_change(datum/source, old_offset, new_offset) SIGNAL_HANDLER @@ -442,26 +445,22 @@ plane = RENDER_PLANE_MASTER render_relay_planes = list() -/atom/movable/screen/plane_master/rendering_plate/master/show_to(mob/mymob) +/atom/movable/screen/plane_master/rendering_plate/master/set_home(datum/plane_master_group/home) . = ..() - if(!.) - return - if(offset == 0) - return // Non 0 offset render plates will relay up to the transparent plane above them, assuming they're not on the same z level as their target of course - var/datum/hud/hud = home.our_hud - // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this - if(hud) - RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) - offset_change(hud?.current_plane_offset || 0) - -/atom/movable/screen/plane_master/rendering_plate/master/hide_from(mob/oldmob) - . = ..() if(offset == 0) return - var/datum/hud/hud = home.our_hud - if(hud) - UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + if(home) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + hud_changed(null, null, home.our_hud) + +/atom/movable/screen/plane_master/rendering_plate/master/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + if(old_hud) + UnregisterSignal(old_hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + if(new_hud) + RegisterSignal(new_hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + offset_change(new_hud?.current_plane_offset || 0) /atom/movable/screen/plane_master/rendering_plate/master/proc/on_offset_change(datum/source, old_offset, new_offset) SIGNAL_HANDLER diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 28ebd80560f..e7ccfff74c1 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -71,7 +71,7 @@ SUBSYSTEM_DEF(parallax) if(picked_parallax == PARALLAX_NONE) return - random_layer = new picked_parallax(null, /* hud_owner = */ null, /* template = */ TRUE) + random_layer = new picked_parallax(null, /* hud_owner = */ null, /* owner = */ null, /* template = */ TRUE) RegisterSignal(random_layer, COMSIG_QDELETING, PROC_REF(clear_references)) random_layer.get_random_look() @@ -85,8 +85,9 @@ SUBSYSTEM_DEF(parallax) //Parallax is one of the first things to be set (during client join), so rarely is anything fast enough to swap it out //That's why we need to swap the layers out for fast joining clients :/ for(var/client/client as anything in GLOB.clients) - client.parallax_layers_cached?.Cut() - client.mob?.hud_used?.update_parallax_pref(client.mob) + // gotta clear things out + client?.parallax_rock?.set_layer_settings(0, FALSE, FALSE) + client.mob?.hud_used?.update_parallax_pref() /datum/controller/subsystem/parallax/proc/clear_references() SIGNAL_HANDLER diff --git a/code/datums/components/hide_weather_planes.dm b/code/datums/components/hide_weather_planes.dm index 3ef26d53b1a..5b7addb199e 100644 --- a/code/datums/components/hide_weather_planes.dm +++ b/code/datums/components/hide_weather_planes.dm @@ -55,7 +55,7 @@ else care_about.hide_plane(our_lad) -/datum/component/hide_weather_planes/proc/new_hud_attached(datum/source, datum/hud/new_hud) +/datum/component/hide_weather_planes/proc/new_hud_attached(datum/source, datum/hud/old_hud, datum/hud/new_hud) SIGNAL_HANDLER attach_hud(new_hud) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index b1e6181f723..8a0d6f56d5f 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -186,8 +186,6 @@ ///A lazy list of atoms we've examined in the last RECENT_EXAMINE_MAX_WINDOW (default 2) seconds, so that we will call [/atom/proc/examine_more] instead of [/atom/proc/examine] on them when examining var/list/recent_examines - var/list/parallax_layers - var/list/parallax_layers_cached var/atom/movable/screen/parallax_home/parallax_rock ///this is the last recorded client eye by SSparallax/fire() var/atom/movable/movingmob @@ -196,13 +194,8 @@ var/dont_animate_parallax /// Direction our current area wants to move parallax var/parallax_movedir = 0 - /// How many parallax layers to show our client - var/parallax_layers_max = 4 /// Timers for the area directional animation, one for each layer var/list/parallax_animate_timers - /// Do we want to do parallax animations at all? - /// Exists to prevent laptop fires - var/do_parallax_animations = TRUE ///Are we locking our movement input? var/movement_locked = FALSE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 7a2eee28d87..0efbf0a819e 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -645,8 +645,6 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( QDEL_NULL(tooltips) QDEL_NULL(loot_panel) QDEL_NULL(parallax_rock) - QDEL_LIST(parallax_layers_cached) - parallax_layers = null seen_messages = null Master.UpdateTickRate() ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening diff --git a/code/modules/client/preferences/parallax.dm b/code/modules/client/preferences/parallax.dm index 24cccce2da6..a39a8edd489 100644 --- a/code/modules/client/preferences/parallax.dm +++ b/code/modules/client/preferences/parallax.dm @@ -10,6 +10,7 @@ PARALLAX_HIGH, PARALLAX_MED, PARALLAX_LOW, + PARALLAX_BOOMER, PARALLAX_DISABLE, ) @@ -17,7 +18,7 @@ return PARALLAX_HIGH /datum/preference/choiced/parallax/apply_to_client(client/client, value) - client.mob?.hud_used?.update_parallax_pref(client?.mob) + client.mob?.hud_used?.update_parallax_pref() /datum/preference/choiced/parallax/deserialize(input, datum/preferences/preferences) // Old preferences were numbers, which causes annoyances when diff --git a/icons/effects/old_parallax.dmi b/icons/effects/old_parallax.dmi new file mode 100644 index 00000000000..cc58e7390e4 Binary files /dev/null and b/icons/effects/old_parallax.dmi differ