diff --git a/aurorastation.dme b/aurorastation.dme index b8e05b63ca0..9ac887ebec8 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -314,7 +314,6 @@ #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\skybox.dm" #include "code\_onclick\hud\spell_screen_objects.dm" -#include "code\_onclick\hud\rendering\_renderer.dm" #include "code\_onclick\hud\screen_object_types\ai_screen_objs.dm" #include "code\_onclick\hud\screen_object_types\borer.dm" #include "code\_onclick\hud\screen_object_types\internals.dm" @@ -490,6 +489,7 @@ #include "code\datums\elements\_element.dm" #include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\empprotection.dm" +#include "code\datums\elements\temporary.dm" #include "code\datums\ert\corporate.dm" #include "code\datums\ert\outsider.dm" #include "code\datums\ert\responseteam.dm" @@ -1117,6 +1117,7 @@ #include "code\game\objects\effects\overlays.dm" #include "code\game\objects\effects\plastic_explosive.dm" #include "code\game\objects\effects\portals.dm" +#include "code\game\objects\effects\shockwave.dm" #include "code\game\objects\effects\spiders.dm" #include "code\game\objects\effects\step_triggers.dm" #include "code\game\objects\effects\chem\chemsmoke.dm" @@ -3552,6 +3553,9 @@ #include "code\modules\recycling\disposal-construction.dm" #include "code\modules\recycling\disposal.dm" #include "code\modules\recycling\sortingmachinery.dm" +#include "code\modules\rendering\plane_master.dm" +#include "code\modules\rendering\plane_master_controller.dm" +#include "code\modules\rendering\render_plate.dm" #include "code\modules\research\circuitprinter.dm" #include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\protolathe.dm" diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index c5716d23680..c3dd7946134 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -132,12 +132,10 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin icon = 'icons/effects/fire.dmi' icon_state = "3" appearance_flags = PIXEL_SCALE | NO_CLIENT_COLOR - render_target = HEAT_EFFECT_TARGET mouse_opacity = MOUSE_OPACITY_TRANSPARENT /obj/fire //Icon for fire on turfs. - anchored = 1 mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index babfc801508..7845f352d8a 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -1,6 +1,6 @@ /* smoothing_flags */ ///Do not smooth -#define SMOOTH_FALSE BITFLAG(0) +#define SMOOTH_FALSE 0 ///Smooths with exact specified types or just itself #define SMOOTH_TRUE BITFLAG(1) ///Smooths with all subtypes of specified types or just itself (this value can replace SMOOTH_TRUE) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index b789a52a419..8f5c706d47e 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -16,36 +16,35 @@ FLOAT_PLANE = -32767 */ -#define LOWEST_PLANE -200 +/// NEVER HAVE ANYTHING BELOW THIS PLANE ADJUST IF YOU NEED MORE SPACE +#define LOWEST_EVER_PLANE -200 -#define CLICKCATCHER_PLANE -100 +#define CLICKCATCHER_PLANE -92 -#define SPACE_PLANE -99 +#define SPACE_PLANE -91 #define SPACE_LAYER 1 -#define SKYBOX_PLANE -98 +#define SKYBOX_PLANE -90 #define SKYBOX_LAYER 1 -#define DUST_PLANE -97 +#define DUST_PLANE -82 #define DEBRIS_LAYER 1 #define DUST_LAYER 2 +#define OPENSPACE_BACKDROP_PLANE -81 +#define OPEN_SPACE_PLANE_START -80 // Openspace uses planes -80 through -70. -#define OPENTURF_MAX_PLANE -70 +// Do no put anything between these two, adjust more z level support as needed +#define OPEN_SPACE_PLANE_END -70 #define OPENTURF_MAX_DEPTH 10 // The maxiumum number of planes deep we'll go before we just dump everything on the same plane. -#define OVER_OPENSPACE_PLANE -4 - #define HEAT_EFFECT_PLANE -4 -#define HEAT_EFFECT_TARGET "*heat" -#define COLD_EFFECT_TARGET "*cold" -#define COLD_EFFECT_BACK_TARGET "*coldb" -#define HEAT_COMPOSITE_TARGET "*heatc" #define WARP_EFFECT_PLANE -3 #define BLACKNESS_PLANE 0 //Blackness plane as per DM documentation. -#define DEFAULT_PLANE 1 +/// Game Plane, where most of the game objects reside +#define GAME_PLANE 1 #define PLATING_LAYER 1 //ABOVE PLATING #define HOLOMAP_LAYER 1.01 @@ -135,10 +134,8 @@ #define POINTER_LAYER 4.27 #define MIMICED_LIGHTING_LAYER 4.28 // Z-Mimic-managed lighting - //FLY_LAYER 5 - //OBSERVER - #define OBSERVER_LAYER 5.1 #define OBFUSCATION_LAYER 5.2 + //FLY_LAYER 5 #define OVERMAP_SECTOR_LAYER 60 #define OVERMAP_IMPORTANT_SECTOR_LAYER 61 @@ -147,27 +144,37 @@ #define AREA_LAYER 999 -#define OBSERVER_PLANE 3 +/// Above Game Plane. For things which are above game objects, but below screen effects. +#define ABOVE_GAME_PLANE 2 -#define ROOF_PLANE 4 +#define ROOF_PLANE 3 -#define LIGHTING_PLANE 5 +#define DISPLACEMENT_PLATE_RENDER_LAYER 4 +#define DISPLACEMENT_PLATE_RENDER_TARGET "*DISPLACEMENT_PLATE_RENDER_TARGET" + +#define GHOST_PLANE 80 + +#define LIGHTING_PLANE 100 #define LIGHTING_LAYER 1 -#define EFFECTS_ABOVE_LIGHTING_PLANE 6 +#define BALLOON_CHAT_PLANE 110 + +#define ABOVE_LIGHTING_PLANE 150 #define EYE_GLOW_LAYER 1 #define BEAM_PROJECTILE_LAYER 2 #define SUPERMATTER_WALL_LAYER 3 #define LIGHTNING_LAYER 4 -#define FULLSCREEN_PLANE 7 +#define RUNECHAT_PLANE 501 + +#define FULLSCREEN_PLANE 9 #define FULLSCREEN_LAYER 1 #define DAMAGE_LAYER 2 #define IMPAIRED_LAYER 3 #define BLIND_LAYER 4 #define CRIT_LAYER 5 -#define HUD_PLANE 8 +#define HUD_PLANE 1000 #define UNDER_HUD_LAYER 1 #define HUD_BASE_LAYER 2 #define HUD_BELOW_ITEM_LAYER 2.9 @@ -177,32 +184,35 @@ #define RADIAL_BASE_LAYER 6 #define RADIAL_CONTENT_LAYER 7 -#define BALLOON_CHAT_PLANE 9 +#define CINEMATIC_PLANE 1200 + +/*=============================*\ +| | +| PLANE DEFINES | +| | +\*=============================*/ + +#define RENDER_PLANE_GAME 990 +#define RENDER_PLANE_NON_GAME 995 + +#define RENDER_PLANE_MASTER 999 + +/// Plane master controller keys +#define PLANE_MASTERS_GAME "plane_masters_game" +#define PLANE_MASTERS_NON_MASTER "plane_masters_non_master" + +//---------- EMISSIVES ------------- +//Layering order of these is not particularly meaningful. +//Important part is the seperation of the planes for control via plane_master /// This plane masks out lighting, to create an "emissive" effect for e.g glowing screens in otherwise dark areas. -#define EMISSIVE_PLANE 10 +#define EMISSIVE_PLANE 90 #define EMISSIVE_TARGET "*emissive" /// The layer you should use when you -really- don't want an emissive overlay to be blocked. #define EMISSIVE_LAYER_UNBLOCKABLE 9999 -#define RUNECHAT_PLANE 500 - -//-------------------- Rendering --------------------- - -/// Semantics - The final compositor or a filter effect renderer -#define RENDER_GROUP_NONE null - -/// Things to be drawn within the game context -#define RENDER_GROUP_SCENE 990 - -/// Things to be drawn within the screen context -#define RENDER_GROUP_SCREEN 995 - -/// The final render group, for compositing -#define RENDER_GROUP_FINAL 999 - -/// Integer (One of `*_PLANE`). The atom's rendering plane. See `code\__defines\__renderer.dm` for a list of valid planes. Also see the DM Reference for `plane var (atom)`. -/atom/plane = DEFAULT_PLANE +/// The render target used by the emissive layer. +#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" #define DEFAULT_APPEARANCE_FLAGS (PIXEL_SCALE) @@ -215,11 +225,11 @@ layer = HUD_ITEM_LAYER /image/proc/turf_decal_layerise() - plane = DEFAULT_PLANE + plane = GAME_PLANE layer = DECAL_LAYER /image/proc/plating_decal_layerise() - plane = DEFAULT_PLANE + plane = GAME_PLANE layer = DECAL_PLATING_LAYER /atom/proc/reset_plane_and_layer() diff --git a/code/__HELPERS/emissives.dm b/code/__HELPERS/emissives.dm index 7d975a3758d..1c584e6f90c 100644 --- a/code/__HELPERS/emissives.dm +++ b/code/__HELPERS/emissives.dm @@ -1,17 +1,17 @@ /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. -/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = EMPTY_BITFIELD) - var/mutable_appearance/appearance = mutable_appearance(icon = icon, icon_state = icon_state, layer = layer, plane = EMISSIVE_PLANE, flags = appearance_flags|EMISSIVE_APPEARANCE_FLAGS) +/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. +/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE) + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) if(alpha == 255) appearance.color = GLOB.emissive_color else var/alpha_ratio = alpha/255 appearance.color = _EMISSIVE_COLOR(alpha_ratio) - appearance.blend_mode = BLEND_OVERLAY return appearance /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR]. /proc/emissive_blocker(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = EMPTY_BITFIELD, source = null) - var/mutable_appearance/appearance = mutable_appearance(icon = icon, icon_state = icon_state, layer = layer, plane = EMISSIVE_PLANE, flags = appearance_flags|EMISSIVE_APPEARANCE_FLAGS) + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) if(alpha == 255) appearance.color = GLOB.em_block_color else @@ -19,17 +19,3 @@ appearance.color = _EM_BLOCK_COLOR(alpha_ratio) return appearance -// Designed to be a faster version of the above, for most use-cases -/proc/fast_emissive_blocker(atom/make_blocker) - var/mutable_appearance/blocker = new() - blocker.icon = make_blocker.icon - blocker.icon_state = make_blocker.icon_state - blocker.appearance_flags |= make_blocker.appearance_flags | EMISSIVE_APPEARANCE_FLAGS - blocker.dir = make_blocker.dir - if(make_blocker.alpha == 255) - blocker.color = GLOB.em_block_color - else - var/alpha_ratio = make_blocker.alpha/255 - blocker.color = _EM_BLOCK_COLOR(alpha_ratio) - blocker.plane = EMISSIVE_PLANE - return blocker diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 85f2b601027..d40e4f19849 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -274,7 +274,7 @@ /** * Blend atoms */ -/atom/proc/handle_blending(adjacencies, var/list/dir_mods, var/overlay_layer = 3) +/atom/proc/handle_blending(adjacencies, var/list/dir_mods) SHOULD_NOT_SLEEP(TRUE) LAZYINITLIST(dir_mods) @@ -285,7 +285,7 @@ var/turf/T = get_step(src, REVERSE_DIR(adjacency)) if(is_type_in_list(T, can_blend_with)) if(attach_overlay) - AddOverlays("[REVERSE_DIR(adjacency)]_[attach_overlay]", overlay_layer) + AddOverlays("[REVERSE_DIR(adjacency)]_[attach_overlay]") walls_found |= adjacency dir_mods["[adjacency]"] = "-[blend_overlay]" for(var/adjacency in list(N_NORTH, N_SOUTH)) @@ -300,7 +300,7 @@ if(((adjacencies & adjacency) && (adjacencies && diagonal)) && (has_adjacency || has_diagonal)) dir_mods["[adjacency][diagonal]"] = "-[prefix][has_adjacency ? "wall" : "win"]-[suffix][has_diagonal ? "wall" : "win"]" if(attach_overlay) - AddOverlays("[prefix][suffix]_[attach_overlay]", overlay_layer) + AddOverlays("[prefix][suffix]_[attach_overlay]") return dir_mods #undef ndir_to_initial diff --git a/code/__HELPERS/visual_filters.dm b/code/__HELPERS/visual_filters.dm index 15d06fc099a..adc02ce8fa8 100644 --- a/code/__HELPERS/visual_filters.dm +++ b/code/__HELPERS/visual_filters.dm @@ -3,7 +3,7 @@ // All of this ported from TG. // And then ported to Nebula from Polaris. // And then ported to Aurora -/atom/movable +/atom var/list/filter_data // For handling persistent filters /proc/cmp_filter_data_priority(list/A, list/B) @@ -13,14 +13,14 @@ /image/proc/add_filter(filter_name, priority, list/params) filters += filter(arglist(params)) -/atom/movable/proc/add_filter(filter_name, priority, list/params) +/atom/proc/add_filter(name,priority,list/params) LAZYINITLIST(filter_data) var/list/p = params.Copy() p["priority"] = priority - filter_data[filter_name] = p + filter_data[name] = p update_filters() -/atom/movable/proc/update_filters() +/atom/proc/update_filters() filters = null filter_data = sortTim(filter_data, GLOBAL_PROC_REF(cmp_filter_data_priority), TRUE) for(var/f in filter_data) @@ -28,22 +28,59 @@ var/list/arguments = data.Copy() arguments -= "priority" filters += filter(arglist(arguments)) - UPDATE_OO_IF_PRESENT + UNSETEMPTY(filter_data) -/atom/movable/proc/get_filter(filter_name) - if(filter_data && filter_data[filter_name]) - return filters[filter_data.Find(filter_name)] +/atom/proc/get_filter(name) + if(filter_data && filter_data[name]) + return filters[filter_data.Find(name)] -// Polaris Extensions -/atom/movable/proc/remove_filter(filter_name) - var/thing = get_filter(filter_name) - if(thing) - LAZYREMOVE(filter_data, filter_name) - filters -= thing +/atom/proc/remove_filter(name_or_names) + if(!filter_data) + return + + var/found = FALSE + var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names) + + for(var/name in names) + if(filter_data[name]) + filter_data -= name + found = TRUE + + if(found) update_filters() +/atom/proc/clear_filters() + filter_data = null + filters = null + +/** Update a filter's parameter and animate this change. If the filter doesnt exist we won't do anything. + * Basically a [datum/proc/modify_filter] call but with animations. Unmodified filter parameters are kept. + * + * Arguments: + * * name - Filter name + * * new_params - New parameters of the filter + * * time - time arg of the BYOND animate() proc. + * * easing - easing arg of the BYOND animate() proc. + * * loop - loop arg of the BYOND animate() proc. + */ +/atom/proc/transition_filter(name, list/new_params, time, easing, loop) + var/filter = get_filter(name) + if(!filter) + return + + var/list/old_filter_data = filter_data[name] + + var/list/params = old_filter_data.Copy() + for(var/thing in new_params) + params[thing] = new_params[thing] + + animate(filter, new_params, time = time, easing = easing, loop = loop) + for(var/param in params) + filter_data[name][param] = params[param] + + /// Animate a given filter on this atom. All params after the first are passed to animate(). -/atom/movable/proc/animate_filter(filter_name, list/params) +/atom/proc/animate_filter(filter_name, list/params) if (!filter_data || !filter_data[filter_name]) return @@ -54,11 +91,16 @@ // First, animate ourselves. monkeypatched_params[1] = filters[index] animate(arglist(monkeypatched_params)) + . = list("monkeypatched_params" = monkeypatched_params, "index" = index) +/atom/movable/animate_filter(filter_name, list/params) + . = ..() + var/monkeypatched_params = .["monkeypatched_params"] + var/index = .["index"] // If we're being copied by Z-Mimic, update mimics too. if (bound_overlay) for (var/atom/movable/AM as anything in get_above_oo()) - monkeypatched_params[1] = AM.filters[index] + params[1] = AM.filters[index] animate(arglist(monkeypatched_params)) //Helpers to generate lists for filter helpers @@ -75,3 +117,40 @@ .["render_source"] = render_source if(!isnull(flags)) .["flags"] = flags + +/proc/color_matrix_filter(matrix/in_matrix, space) + . = list("type" = "color") + .["color"] = in_matrix + if(!isnull(space)) + .["space"] = space + +/proc/drop_shadow_filter(x, y, size, offset, color) + . = list("type" = "drop_shadow") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(color)) + .["color"] = color + +/proc/gauss_blur_filter(size) + . = list("type" = "blur") + if(!isnull(size)) + .["size"] = size + +/proc/displacement_map_filter(icon, render_source, x, y, size = 32) + . = list("type" = "displace") + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 134b3ccf726..ee8d4f5ba36 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -147,10 +147,32 @@ GLOBAL_LIST(global_huds) var/list/other var/list/atom/movable/screen/hotkeybuttons + /// See "appearance_flags" in the ref, assoc list of "[plane]" = object + var/list/atom/movable/screen/plane_master/plane_masters = list() + ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref + var/list/atom/movable/plane_master_controller/plane_master_controllers = list() + var/atom/movable/screen/movable/action_button/hide_toggle/hide_actions_toggle /datum/hud/New(mob/owner) mymob = owner + + for(var/mytype in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/rendering_plate - /atom/movable/screen/plane_master/open_space) + var/atom/movable/screen/plane_master/instance = new mytype() + plane_masters["[instance.plane]"] = instance + if(owner.client) + instance.backdrop(mymob) + + for(var/z_level in 0 to OPEN_SPACE_PLANE_END - OPEN_SPACE_PLANE_START) //aurora snowflake: our openspace system works bottom up, not top down like CM's + var/atom/movable/screen/plane_master/open_space/instance = new(null, z_level) + plane_masters["[instance.plane]"] = instance + if(owner.client) + instance.backdrop(mymob) + + for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) + var/atom/movable/plane_master_controller/controller_instance = new mytype(null,src) + plane_master_controllers[controller_instance.name] = controller_instance + instantiate() ..() @@ -171,6 +193,9 @@ GLOBAL_LIST(global_huds) // item_action_list = null // ? mymob = null + QDEL_LIST_ASSOC_VAL(plane_masters) + QDEL_LIST_ASSOC_VAL(plane_master_controllers) + . = ..() /datum/hud/proc/hidden_inventory_update() @@ -323,6 +348,15 @@ GLOBAL_LIST(global_huds) mymob.instantiate_hud(src, ui_style, ui_color, ui_alpha) + plane_masters_update() + +/datum/hud/proc/plane_masters_update() + // Plane masters are always shown to OUR mob, never to observers + for(var/thing in plane_masters) + var/atom/movable/screen/plane_master/PM = plane_masters[thing] + PM.backdrop(mymob) + mymob.client.add_to_screen(PM) + /mob/proc/instantiate_hud(datum/hud/HUD, ui_style, ui_color, ui_alpha) SHOULD_NOT_SLEEP(TRUE) SHOULD_CALL_PARENT(FALSE) diff --git a/code/_onclick/hud/rendering/_renderer.dm b/code/_onclick/hud/rendering/_renderer.dm deleted file mode 100644 index a5a7bde03c7..00000000000 --- a/code/_onclick/hud/rendering/_renderer.dm +++ /dev/null @@ -1,442 +0,0 @@ -/* * -* Renderers -* Renderers are virtual objects that act as draw groups of things, including -* other Renderers. Renderers are similar to older uses of PLANE_MASTER but -* employ render targets using the "*" slate prefix to draw off-screen, to be -* composited in a controlled and flexible order and in some cases, reuse for -* visual effects. -*/ - -/// Add one instance of this renderer on mob/Login with no special setup -#define RENDERER_FLAG_AUTO BITFLAG(1) - -/// This renderer can be used with mob/AddRenderer & mob/RemoveRenderer -#define RENDERER_FLAG_OPTIONAL BITFLAG(2) - - -/// The base /renderer definition and defaults. -ABSTRACT_TYPE(/atom/movable/renderer) - appearance_flags = DEFAULT_RENDERER_APPEARANCE_FLAGS - screen_loc = "1,1" - plane = LOWEST_PLANE - blend_mode = BLEND_OVERLAY - - /// A bitfield of RENDERER_* defines. - var/renderer_flags = NONE - - /// The compositing renderer this renderer belongs to. - var/group = RENDER_GROUP_FINAL - - /// The relay movable used to composite this renderer to its group. - var/atom/movable/relay // Also see https://secure.byond.com/forum/?post=2141928 maybe. - - /// Optional blend mode override for the renderer's composition relay. - var/relay_blend_mode - - /// If text, uses the text or, if TRUE, uses "*AUTO-[name]". - var/render_target_name = TRUE - - /// When not shared, the mob associated with this renderer. - var/mob/owner - - -/atom/movable/renderer/Destroy() - QDEL_NULL(relay) - owner = null - return ..() - - -INITIALIZE_IMMEDIATE(/atom/movable/renderer) -/atom/movable/renderer/Initialize(mapload, mob/owner) - . = ..() - if (. == INITIALIZE_HINT_QDEL) - return - src.owner = owner - if (isnull(group)) - if (istext(render_target_name)) - render_target = render_target_name - return - if (istext(render_target_name)) - render_target = render_target_name - else if (render_target_name) - render_target = "*[ckey(name)]" - if (owner?.client?.byond_version < 516) - screen_loc = "CENTER" - relay = new - relay.screen_loc = screen_loc - relay.appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER - relay.name = "[render_target] relay" - relay.mouse_opacity = mouse_opacity - relay.render_source = render_target - relay.layer = (plane + abs(LOWEST_PLANE)) * 0.5 - relay.plane = group - if (isnull(relay_blend_mode)) - relay.blend_mode = blend_mode - else - relay.blend_mode = relay_blend_mode - - -/** -* Graphic preferences -* Some renderers may be able to use a graphic preference to determine how to display effects. -* For example reduce particle counts or filter variables. -*/ -/atom/movable/renderer/proc/GraphicsUpdate() - return - - -/** -* Renderers on /mob -* We attach renderers to mobs for their lifespan. Only mobs with clients get -* renderers, and they are removed again when the mob loses its client. Mobs -* get their own unique renderer instances but it would not be inconceivable -* to share them globally. -*/ - -/// A map of (instance = plane) renderers in use by this mob. -/mob/var/list/atom/movable/renderer/renderer_plane_map - -/// A map of (type = instance) renderers in use by this mob. -/mob/var/list/atom/movable/renderer/path_renderer_map - - -/// Creates the mob's renderers on /Login() -/mob/proc/AddDefaultRenderers() - if (renderer_plane_map) - ClearRenderers() - renderer_plane_map = list() - path_renderer_map = list() - for (var/atom/movable/renderer/renderer as anything in subtypesof(/atom/movable/renderer)) - if (initial(renderer.renderer_flags) & RENDERER_FLAG_AUTO) - renderer = new renderer(null, src) - renderer_plane_map[renderer] = renderer.plane - path_renderer_map[renderer.type] = renderer - if (renderer.relay) - my_client.screen += renderer.relay - my_client.screen += renderer - var/list/zmimic_renderers = list() - path_renderer_map[/atom/movable/renderer/zmimic] = zmimic_renderers - for (var/i = 0 to OPENTURF_MAX_DEPTH) - var/atom/movable/renderer/zmimic/renderer = new (null, src, OPENTURF_MAX_PLANE - i) - renderer_plane_map[renderer] = renderer.plane - zmimic_renderers += renderer - if (renderer.relay) - my_client.screen += renderer.relay - my_client.screen += renderer - - -/// Removes the mob's renderers on /Logout() -/mob/proc/ClearRenderers() - if (my_client) - for (var/atom/movable/renderer/renderer as anything in renderer_plane_map) - if (renderer.relay) - my_client.screen -= renderer.relay - my_client.screen -= renderer - qdel(renderer) - renderer_plane_map = null - path_renderer_map = null - - -/// Returns the renderer instance of_type if the mob has one and it is not shared. -/mob/proc/GetRenderer(atom/movable/renderer/of_type) - if (!my_client) - return - return path_renderer_map[of_type] - - -/// Adds a non-main renderer to the mob by type if the mob doesn't already have it. -/mob/proc/AddRenderer(atom/movable/renderer/of_type) - if (!my_client) - return - if (~initial(of_type.renderer_flags) & RENDERER_FLAG_OPTIONAL) - return - if (of_type in path_renderer_map) - return - var/atom/movable/renderer/renderer = new of_type (null, src) - if (renderer.relay) - my_client.screen += renderer.relay - my_client.screen += renderer - renderer_plane_map[renderer] = renderer.plane - path_renderer_map[of_type] = renderer - return renderer - - -/// Removes a non-main renderer to the mob by type. -/mob/proc/RemoveRenderer(atom/movable/renderer/of_type) - if (!my_client) - return - if (~initial(of_type.renderer_flags) & RENDERER_FLAG_OPTIONAL) - return - if (!length(path_renderer_map)) - return - var/atom/movable/renderer/renderer = path_renderer_map[of_type] - if (!renderer) - return - if (renderer.relay) - my_client.screen -= renderer.relay - my_client.screen -= renderer - path_renderer_map -= of_type - renderer_plane_map -= renderer - qdel(renderer) - - -/* * -* Plane Renderers -* We treat some renderers as planes with layers. When some atom has the same plane -* as a Plane Renderer, it is drawn by that renderer. The layer of the atom determines -* its draw order within the scope of the renderer. The draw order of same-layered things -* is probably by atom contents order, but can be assumed not to matter - if it's visibly -* incorrect, it should have a more appropriate layer value. -* Higher plane values are composited over lower. Here, they are ordered from under to over. -*/ - - -/// Handles byond internal letterboxing. Avoid touching. -/atom/movable/renderer/letterbox - name = "Letterbox" - group = RENDER_GROUP_SCENE - plane = BLACKNESS_PLANE - blend_mode = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO - - -/atom/movable/renderer/space - name = "Space" - group = RENDER_GROUP_SCENE - plane = SPACE_PLANE - renderer_flags = RENDERER_FLAG_AUTO - - -/atom/movable/renderer/skybox - name = "Skybox" - group = RENDER_GROUP_SCENE - plane = SKYBOX_PLANE - relay_blend_mode = BLEND_MULTIPLY - renderer_flags = RENDERER_FLAG_AUTO - - -/atom/movable/renderer/zmimic - name = "Zrenderer" - group = RENDER_GROUP_SCENE - - -/atom/movable/renderer/zmimic/Initialize(mapload, _owner, _plane) - plane = _plane - name = "Zrenderer [plane]" - return ..() - - -// Draws the game world; live mobs, items, turfs, etc. -/atom/movable/renderer/game - name = "Game" - group = RENDER_GROUP_SCENE - plane = DEFAULT_PLANE - renderer_flags = RENDERER_FLAG_AUTO - - -/// Draws observers; ghosts, camera eyes, etc. -/atom/movable/renderer/observers - name = "Observers" - group = RENDER_GROUP_SCENE - plane = OBSERVER_PLANE - renderer_flags = RENDERER_FLAG_AUTO - - -/// Draws darkness effects. -/atom/movable/renderer/lighting - name = "Lighting" - group = RENDER_GROUP_SCENE - plane = LIGHTING_PLANE - relay_blend_mode = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO - - -/atom/movable/renderer/lighting/Initialize() - . = ..() - filters += filter( - type = "alpha", - render_source = EMISSIVE_TARGET, - flags = MASK_INVERSE - ) - - -/// Draws visuals that should not be affected by darkness. -/atom/movable/renderer/above_lighting - name = "Above Lighting" - group = RENDER_GROUP_SCENE - plane = EFFECTS_ABOVE_LIGHTING_PLANE - renderer_flags = RENDERER_FLAG_AUTO - - -/// Draws full screen visual effects, like pain and bluespace. -/atom/movable/renderer/screen_effects - name = "Screen Effects" - group = RENDER_GROUP_SCENE - plane = FULLSCREEN_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO - - -/// Draws user interface elements. -/atom/movable/renderer/interface - name = "Interface" - group = RENDER_GROUP_SCREEN - plane = HUD_PLANE - renderer_flags = RENDERER_FLAG_AUTO - -/// Draws balloon alert elements. NOT RUNECHAT -/atom/movable/renderer/balloon_alert - name = "Balloon Chat" - group = RENDER_GROUP_SCREEN - plane = BALLOON_CHAT_PLANE - renderer_flags = RENDERER_FLAG_AUTO - - -/* * -* Group renderers -* We treat some renderers as render groups that other renderers subscribe to. Renderers -* subscribe themselves to groups by setting a group value equal to the plane of a Group -* Renderer. This value is used for the Renderer's relay to include it into the Group, and -* the Renderer's plane is used as the relay's layer. -* Group renderers can subscribe themselves to other Group Renderers. This allows for more -* granular manipulation of how the final scene is composed. -*/ - - -/// Render group for stuff INSIDE the typical game context - people, items, lighting, etc. -/atom/movable/renderer/scene_group - name = "Scene Group" - group = RENDER_GROUP_FINAL - plane = RENDER_GROUP_SCENE - renderer_flags = RENDERER_FLAG_AUTO - - -/// Render group for stuff OUTSIDE the typical game context - UI, full screen effects, etc. -/atom/movable/renderer/screen_group - name = "Screen Group" - group = RENDER_GROUP_FINAL - plane = RENDER_GROUP_SCREEN - renderer_flags = RENDERER_FLAG_AUTO - - -/// Render group for final compositing before user display. -/atom/movable/renderer/final_group - name = "Final Group" - group = RENDER_GROUP_NONE - plane = RENDER_GROUP_FINAL - renderer_flags = RENDERER_FLAG_AUTO - - -/* * -* Effect Renderers -* Some renderers are used to produce complex screen effects. These are drawn using filters -* rather than composition groups, and may be added to another renderer in the following -* fashion. Setting a render_target_name with no group is the expected patter for Effect -* Renderers as it allows them to draw to a slate that will be empty unless a relevant -* behavior, such as the effect atom below, causes them to be noticeable. -*/ - - -/// Renders the /obj/effect/warp example effect as well as gravity catapult effects -/atom/movable/renderer/warp - name = "Warp Effect" - group = RENDER_GROUP_NONE - plane = WARP_EFFECT_PLANE - render_target_name = "*warp" - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO - - -//Similar to warp but not as strong -/atom/movable/renderer/heat - name = "Heat Effect" - group = RENDER_GROUP_NONE - plane = HEAT_EFFECT_PLANE - render_target_name = HEAT_COMPOSITE_TARGET - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO - - var/obj/gas_heat_object - var/obj/gas_cold_object - - -/atom/movable/renderer/heat/Initialize() - . = ..() - GraphicsUpdate() - -/atom/movable/renderer/heat/GraphicsUpdate() - if (!ismob(owner)) - return - if (gas_heat_object) - vis_contents -= gas_heat_object - if (gas_cold_object) - vis_contents -= gas_cold_object - QDEL_NULL(gas_heat_object) - QDEL_NULL(gas_cold_object) - gas_cold_object = new /obj/particle_emitter/mist/gas - gas_heat_object = new /obj/particle_emitter/heat/high - vis_contents += gas_heat_object - // if (config.enable_cold_mist) - // vis_contents += gas_cold_object - -/atom/movable/renderer/scene_group/Initialize() - . = ..() - filters += filter( - type = "displace", - render_source = "*warp", - size = 5 - ) - filters += filter( - type = "displace", - render_source = HEAT_COMPOSITE_TARGET, - size = 2.5 - ) - - -/*! - * Emmissives work by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. - * - * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color. - * Emissive blockers are pasted with an atom color that converts them to be entirely some different color. - * Emissive overlays and emissive blockers are put onto the same plane. - * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects. - * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is. - * This is then used to alpha mask the lighting plane. - * - * This works best if emissive overlays applied only to objects that emit light, - * since luminosity=0 turfs may not be rendered. - */ - - -/atom/movable/renderer/emissive - name = "Emissive" - group = RENDER_GROUP_NONE - plane = EMISSIVE_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - render_target_name = EMISSIVE_TARGET - renderer_flags = RENDERER_FLAG_AUTO - - -/atom/movable/renderer/emissive/Initialize() - . = ..() - filters += filter( - type = "color", - color = GLOB.em_mask_matrix - ) - - - - - -/* - AURORA SNOWFLAKES -*/ - -/atom/movable/renderer/roofs - name = "Roofs" - group = RENDER_GROUP_SCENE - plane = ROOF_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - renderer_flags = RENDERER_FLAG_AUTO diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index f920cc74a0d..1a4c5a2dac3 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -360,7 +360,7 @@ if(!isopenturf(above_turf)) continue var/image/point_up = image(icon = 'icons/mob/screen/generic.dmi', icon_state = "arrow_up", loc = T) - point_up.plane = DEFAULT_PLANE + point_up.plane = GAME_PLANE point_up.layer = POINTER_LAYER viewer_client?.images += point_up addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_image_from_client), point_up, viewer_client), 3 SECONDS) diff --git a/code/controllers/subsystems/explosives.dm b/code/controllers/subsystems/explosives.dm index 92dd55727f2..de5a6d11d35 100644 --- a/code/controllers/subsystems/explosives.dm +++ b/code/controllers/subsystems/explosives.dm @@ -184,6 +184,9 @@ SUBSYSTEM_DEF(explosives) E.set_up(epicenter) E.start() + if(power >= 9) + new /obj/effect/shockwave(epicenter, power / 2) + var/x0 = epicenter.x var/y0 = epicenter.y var/z0 = epicenter.z @@ -329,6 +332,9 @@ SUBSYSTEM_DEF(explosives) var/sound/explosion_sound = sound(get_sfx(/singleton/sound_category/explosion_sound)) + if(power >= 100) + new /obj/effect/shockwave(epicenter, power / 60) + for (var/thing in GLOB.player_list) var/mob/M = thing var/reception = EXPLFX_BOTH diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index e28f7189932..4e914160727 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -106,6 +106,8 @@ SUBSYSTEM_DEF(overlays) result += GetStateAppearance(icon, entry) else if (isicon(entry)) result += GetIconAppearance(entry) + else if (istype(entry, /mutable_appearance)) + result += entry else if (isloc(entry)) if (entry.atom_flags & ATOM_AWAITING_OVERLAY_UPDATE) diff --git a/code/controllers/subsystems/processing/shuttle.dm b/code/controllers/subsystems/processing/shuttle.dm index 52f2d16ba84..fd4816546cb 100644 --- a/code/controllers/subsystems/processing/shuttle.dm +++ b/code/controllers/subsystems/processing/shuttle.dm @@ -28,6 +28,9 @@ SUBSYSTEM_DEF(shuttle) var/tmp/list/working_shuttles + /// The destination helper for the cargo elevator. + var/obj/effect/landmark/destination_helper/cargo_elevator/cargo_dest_helper + /datum/controller/subsystem/shuttle/Initialize() last_landmark_registration_time = world.time for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more. diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index 5f0dc773d14..dc600b5cfa7 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -171,7 +171,7 @@ SUBSYSTEM_DEF(zcopy) if (!T.below) // Z-turf on the bottom-most level, just fake-copy space. flush_z_state(T) if(T.z_flags & ZM_MIMIC_BASETURF) - simple_appearance_copy(T, get_base_turf_by_area(T), OPENTURF_MAX_PLANE) + simple_appearance_copy(T, get_base_turf_by_area(T), OPEN_SPACE_PLANE_END) else simple_appearance_copy(T, SSskybox.space_appearance_cache[(((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25) + 1]) @@ -199,7 +199,7 @@ SUBSYSTEM_DEF(zcopy) var/turf_depth turf_depth = T.z_depth = zlev_maximums[Td.z] - Td.z - var/t_target = OPENTURF_MAX_PLANE - turf_depth // This is where the turf (but not the copied atoms) gets put. + var/t_target = OPEN_SPACE_PLANE_END - turf_depth // This is where the turf (but not the copied atoms) gets put. // Turf is set to mimic baseturf, handle that and bail. @@ -261,7 +261,7 @@ SUBSYSTEM_DEF(zcopy) var/atom/movable/openspace/turf_mimic/DC = T.below.mimic_above_copy DC.appearance = T.below DC.mouse_opacity = initial(DC.mouse_opacity) - DC.plane = OPENTURF_MAX_PLANE + DC.plane = OPEN_SPACE_PLANE_END else if (T.below.mimic_above_copy) QDEL_NULL(T.below.mimic_above_copy) @@ -301,7 +301,7 @@ SUBSYSTEM_DEF(zcopy) // If we're a turf overlay (the mimic for a non-OVERWRITE turf), we need to make sure copies of us respect space parallax too if (T.z_eventually_space) // Yes, this is an awful hack; I don't want to add yet another override_* var. - override_depth = OPENTURF_MAX_PLANE - SPACE_PLANE + override_depth = OPEN_SPACE_PLANE_END - SPACE_PLANE if (/atom/movable/openspace/turf_mimic) original_z += 1 @@ -385,7 +385,7 @@ SUBSYSTEM_DEF(zcopy) OO.appearance = OO.associated_atom OO.z_flags = OO.associated_atom.z_flags - OO.plane = OPENTURF_MAX_PLANE - OO.depth + OO.plane = OPEN_SPACE_PLANE_END - OO.depth OO.opacity = FALSE OO.queued = 0 @@ -464,7 +464,7 @@ SUBSYSTEM_DEF(zcopy) // Don't fixup the root object's plane. if (depth > 0) switch (appearance:plane) - if (DEFAULT_PLANE, FLOAT_PLANE) + if (GAME_PLANE, FLOAT_PLANE) plane_needs_fix = FALSE //For lint else plane_needs_fix = TRUE @@ -513,7 +513,7 @@ SUBSYSTEM_DEF(zcopy) var/mutable_appearance/MA = new(appearance) if (plane_needs_fix) - MA.plane = depth == 0 ? DEFAULT_PLANE : FLOAT_PLANE + MA.plane = depth == 0 ? GAME_PLANE : FLOAT_PLANE MA.layer = FLY_LAYER // probably fine if (fixed_overlays) @@ -584,7 +584,7 @@ SUBSYSTEM_DEF(zcopy) VTO.computed_depth = SSzcopy.zlev_maximums[Tbelow.z] - Tbelow.z VTO.appearance = Tbelow VTO.parent = Tbelow - VTO.plane = OPENTURF_MAX_PLANE - VTO.computed_depth + VTO.plane = OPEN_SPACE_PLANE_END - VTO.computed_depth found_oo += VTO temp_objects += VTO @@ -616,7 +616,7 @@ SUBSYSTEM_DEF(zcopy) atoms_list_list -= "0" for (var/d in 0 to OPENTURF_MAX_DEPTH) - var/pl = OPENTURF_MAX_PLANE - d + var/pl = OPEN_SPACE_PLANE_END - d if (!atoms_list_list["[pl]"]) out += "Depth [d], plane [pl] — empty" continue diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 6768a1d1f6c..7d57dd38e10 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -206,7 +206,7 @@ /obj/effect/ebeam mouse_opacity = MOUSE_OPACITY_TRANSPARENT anchored = 1 - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE layer = BEAM_PROJECTILE_LAYER blend_mode = BLEND_ADD var/datum/beam/owner diff --git a/code/datums/components/overhead_emote/overhead_emote_singleton.dm b/code/datums/components/overhead_emote/overhead_emote_singleton.dm index 3c93d1038dc..14b70384519 100644 --- a/code/datums/components/overhead_emote/overhead_emote_singleton.dm +++ b/code/datums/components/overhead_emote/overhead_emote_singleton.dm @@ -9,6 +9,7 @@ ABSTRACT_TYPE(/singleton/overhead_emote) var/image/image = image(icon, icon_state) image.pixel_y = 18 + target.get_floating_chat_y_offset() image.pixel_x = target.get_floating_chat_x_offset() + image.plane = ABOVE_GAME_PLANE return image /singleton/overhead_emote/proc/start_emote(var/mob/parent, var/mob/victim) diff --git a/code/datums/elements/temporary.dm b/code/datums/elements/temporary.dm new file mode 100644 index 00000000000..931e56d7139 --- /dev/null +++ b/code/datums/elements/temporary.dm @@ -0,0 +1,15 @@ +/// Sets an effect to delete itself after a specific amount of time +/datum/element/temporary + +/datum/element/temporary/Attach(datum/target, duration) + . = ..() + if (. == ELEMENT_INCOMPATIBLE) + return + if (!istype(target, /obj/effect)) + return ELEMENT_INCOMPATIBLE + addtimer(CALLBACK(src, PROC_REF(delete_effect), WEAKREF(target)), duration) + +/datum/element/temporary/proc/delete_effect(datum/weakref/target_ref) + SIGNAL_HANDLER + if (target_ref.resolve()) + qdel(target_ref) diff --git a/code/datums/langchat/langchat.dm b/code/datums/langchat/langchat.dm index 7615c24a9a5..a2c4ce351e6 100644 --- a/code/datums/langchat/langchat.dm +++ b/code/datums/langchat/langchat.dm @@ -52,13 +52,12 @@ if(!langchat_image) langchat_image = image(null, src) langchat_image.layer = 20 - langchat_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + langchat_image.plane = RUNECHAT_PLANE langchat_image.appearance_flags = NO_CLIENT_COLOR|KEEP_APART|RESET_COLOR|RESET_TRANSFORM langchat_image.maptext_y = langchat_height langchat_image.maptext_height = 64 langchat_image.maptext_y -= LANGCHAT_MESSAGE_POP_Y_SINK langchat_image.maptext_x = get_maxptext_x_offset(langchat_image) - langchat_image.filters = filter(type="drop_shadow", size = 1, color = COLOR_BLACK) langchat_image.pixel_y = 0 langchat_image.alpha = 0 diff --git a/code/defines/mutable_appearance.dm b/code/defines/mutable_appearance.dm index 9c1ab3b381f..b59295e3f33 100644 --- a/code/defines/mutable_appearance.dm +++ b/code/defines/mutable_appearance.dm @@ -9,17 +9,16 @@ /mutable_appearance/New(mutable_appearance/to_copy) ..() - if(!to_copy) - plane = FLOAT_PLANE + plane = FLOAT_PLANE // Helper similar to image() -/proc/mutable_appearance(icon, icon_state, color, flags = DEFAULT_APPEARANCE_FLAGS | RESET_COLOR | RESET_ALPHA, plane = FLOAT_PLANE, layer = FLOAT_LAYER) +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE) RETURN_TYPE(/mutable_appearance) var/mutable_appearance/MA = new() MA.icon = icon MA.icon_state = icon_state - MA.color = color - MA.appearance_flags = flags - MA.plane = plane MA.layer = layer + MA.plane = plane + MA.alpha = alpha + MA.appearance_flags |= appearance_flags return MA diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 340aeb40347..d2cc218e2f3 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -6,6 +6,9 @@ */ /atom + plane = GAME_PLANE + layer = TURF_LAYER + appearance_flags = DEFAULT_APPEARANCE_FLAGS /// pass_flags that we are. If any of this matches a pass_flag on a moving thing, by default, we let them through. var/pass_flags_self = NONE @@ -24,9 +27,6 @@ var/update_icon_on_init = FALSE // Default to 'no'. - layer = TURF_LAYER - appearance_flags = DEFAULT_APPEARANCE_FLAGS - var/level = 2 var/atom_flags = 0 var/init_flags = 0 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b0aa198a85b..37e603e4f57 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -372,17 +372,16 @@ /atom/movable/proc/update_emissive_blocker() switch (blocks_emissive) if (EMISSIVE_BLOCK_GENERIC) - em_block = fast_emissive_blocker(src) + var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = EMISSIVE_PLANE, alpha = src.alpha) + gen_emissive_blocker.color = GLOB.em_block_color + gen_emissive_blocker.dir = dir + gen_emissive_blocker.appearance_flags |= appearance_flags + em_block = gen_emissive_blocker + if (EMISSIVE_BLOCK_UNIQUE) - if (!em_block && !QDELING(src)) - appearance_flags |= KEEP_TOGETHER - render_target = REF(src) - em_block = emissive_blocker( - icon = icon, - icon_state = icon_state, - appearance_flags = appearance_flags, - source = render_target - ) + render_target = REF(src) + em_block = new(src, render_target) + return em_block /atom/movable/update_icon() diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index 4902ea80cdd..1ae268a6e9d 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -6,7 +6,7 @@ icon = 'icons/turf/space.dmi' icon_state = "bluespace-n" - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE layer = SUPERMATTER_WALL_LAYER light_color = COLOR_CYAN_BLUE light_power = 6 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index dc06bd597ca..75973b7e3eb 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -322,19 +322,19 @@ update_flag if(update_flag & 2) AddOverlays("can-connector") if(update_flag & 4) - var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o0", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o0", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) set_light(1.4, 1, COLOR_RED_LIGHT) if(update_flag & 8) - var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o1", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o1", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) set_light(1.4, 1, COLOR_RED_LIGHT) else if(update_flag & 16) - var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o2", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o2", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) set_light(1.4, 1, COLOR_YELLOW) else if(update_flag & 32) - var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o3", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o3", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) set_light(1.4, 1, COLOR_BRIGHT_GREEN) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index b5cc4077644..ba930cc949c 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1095,31 +1095,31 @@ About the new airlock wires panel: switch(state) if(AIRLOCK_CLOSED) if(lights && locked) - lights_overlay = overlay_image(bolts_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + lights_overlay = overlay_image(bolts_file, plane = ABOVE_LIGHTING_PLANE) set_light(1, 2, COLOR_RED_LIGHT) if(AIRLOCK_DENY) if(lights) - lights_overlay = overlay_image(deny_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + lights_overlay = overlay_image(deny_file, plane = ABOVE_LIGHTING_PLANE) set_light(1, 2, COLOR_RED_LIGHT) if(AIRLOCK_EMAG) - sparks_overlay = overlay_image(emag_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + sparks_overlay = overlay_image(emag_file, plane = ABOVE_LIGHTING_PLANE) if(AIRLOCK_CLOSING) if(lights) - lights_overlay = overlay_image(lights_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + lights_overlay = overlay_image(lights_file, plane = ABOVE_LIGHTING_PLANE) set_light(1, 2, COLOR_LIME) if(AIRLOCK_OPENING) if(lights) - lights_overlay = overlay_image(lights_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + lights_overlay = overlay_image(lights_file, plane = ABOVE_LIGHTING_PLANE) set_light(1, 2, COLOR_LIME) if(stat & BROKEN) - damage_overlay = overlay_image(sparks_broken_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + damage_overlay = overlay_image(sparks_broken_file, plane = ABOVE_LIGHTING_PLANE) else if (health < maxhealth * 3/4 && !(stat & NOPOWER)) - damage_overlay = overlay_image(sparks_damaged_file, plane = EFFECTS_ABOVE_LIGHTING_PLANE) + damage_overlay = overlay_image(sparks_damaged_file, plane = ABOVE_LIGHTING_PLANE) if(welded) weld_overlay = welded_file diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b52b5c40ba3..8a2c19fbe2d 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -498,7 +498,7 @@ if(blocked) AddOverlays("welded") if(pdiff_alert) - AddOverlays(overlay_image(icon, icon_state = "palert", plane = EFFECTS_ABOVE_LIGHTING_PLANE)) + AddOverlays(overlay_image(icon, icon_state = "palert", plane = ABOVE_LIGHTING_PLANE)) do_set_light = 1 if(dir_alerts) for (var/d = 1; d <= 4; d++) @@ -509,9 +509,9 @@ if (!dir_alerts[d]) continue if (dir_alerts[d] & FIREDOOR_ALERT_COLD) - AddOverlays(overlay_image(icon, icon_state = "alert_cold", plane = EFFECTS_ABOVE_LIGHTING_PLANE)) + AddOverlays(overlay_image(icon, icon_state = "alert_cold", plane = ABOVE_LIGHTING_PLANE)) if (dir_alerts[d] & FIREDOOR_ALERT_HOT) - AddOverlays(overlay_image(icon, icon_state = "alert_hot", plane = EFFECTS_ABOVE_LIGHTING_PLANE)) + AddOverlays(overlay_image(icon, icon_state = "alert_hot", plane = ABOVE_LIGHTING_PLANE)) do_set_light = TRUE else diff --git a/code/game/machinery/rotating_alarm.dm b/code/game/machinery/rotating_alarm.dm index 2e98f9160f3..1941597242e 100644 --- a/code/game/machinery/rotating_alarm.dm +++ b/code/game/machinery/rotating_alarm.dm @@ -6,7 +6,7 @@ var/_offset = 30 var/_color = COLOR_ORANGE alpha = 200 - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE layer = EYE_GLOW_LAYER mouse_opacity = 0 diff --git a/code/game/machinery/stargazer.dm b/code/game/machinery/stargazer.dm index 7324b168cda..b6cdd8a8930 100644 --- a/code/game/machinery/stargazer.dm +++ b/code/game/machinery/stargazer.dm @@ -16,7 +16,7 @@ /obj/machinery/stargazer/Initialize(mapload, d, populate_components) . = ..() star_system_image = image(icon, null, "stargazer_[SSatlas.current_sector.name]") - star_system_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + star_system_image.plane = ABOVE_LIGHTING_PLANE star_system_image.layer = SUPERMATTER_WALL_LAYER power_change() diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 67b27686a85..0ff57e90374 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -60,14 +60,14 @@ ClearOverlays() if (engaged) var/image/I = image(icon, src, "[initial(icon_state)]_active_overlay") - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE AddOverlays(I) set_light(4, 0.4) else set_light(0) if (operable()) var/image/I = image(icon, src, "[initial(icon_state)]_idle_overlay") - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE AddOverlays(I) /obj/machinery/teleport/pad/proc/within_range(var/target) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index cc49c75a021..5f2f869b07e 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -12,6 +12,7 @@ would spawn and follow the beaker, even if it is carried or thrown. mouse_opacity = MOUSE_OPACITY_TRANSPARENT unacidable = 1//So effect are not targeted by alien acid. pass_flags = PASSTABLE | PASSGRILLE + blocks_emissive = EMISSIVE_BLOCK_GENERIC /obj/effect/Destroy() if(reagents) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index f00910606d7..566fd917a08 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -85,16 +85,3 @@ /obj/effect/constructing_effect/proc/end() qdel(src) - -/// Example of a warp filter -/obj/effect/effect/warp - plane = WARP_EFFECT_PLANE - appearance_flags = PIXEL_SCALE - icon = 'icons/effects/352x352.dmi' - icon_state = "singularity_s11" - pixel_x = -176 - pixel_y = -176 - -/obj/effect/obfuscation - icon_state = "1" - layer = OBFUSCATION_LAYER diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index aa0407443fa..7a55e494dc2 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -15,7 +15,7 @@ icon='icons/effects/beam.dmi' icon_state="b_beam" blend_mode = BLEND_ADD - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE animate_movement = FALSE var/tmp/atom/BeamSource @@ -47,7 +47,7 @@ name = "bluespace" icon = 'icons/turf/space.dmi' icon_state = "bluespacify" - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE layer = SUPERMATTER_WALL_LAYER /obj/effect/overlay/temp diff --git a/code/game/objects/effects/shockwave.dm b/code/game/objects/effects/shockwave.dm new file mode 100644 index 00000000000..d100de1dba0 --- /dev/null +++ b/code/game/objects/effects/shockwave.dm @@ -0,0 +1,25 @@ +//------------------------------------------ +//Shockwaves +//------------------------------------------ + + +/obj/effect/shockwave + icon = 'icons/effects/shockwave.dmi' + icon_state = "shockwave" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = DISPLACEMENT_PLATE_RENDER_LAYER + pixel_x = -496 + pixel_y = -496 + vis_flags = 0 + +/obj/effect/shockwave/Initialize(mapload, radius, speed, easing_type = LINEAR_EASING, y_offset, x_offset) + . = ..() + if(!speed) + speed = 1 + if(y_offset) + pixel_y += y_offset + if(x_offset) + pixel_x += x_offset + AddElement(/datum/element/temporary, 0.5 * radius * speed) + transform = matrix().Scale(32 / 1024, 32 / 1024) + animate(src, time = 0.5 * radius * speed, transform=matrix().Scale((32 / 1024) * radius * 1.5, (32 / 1024) * radius * 1.5), easing = easing_type) diff --git a/code/game/objects/items/camping.dm b/code/game/objects/items/camping.dm index e41ccdc9f2f..0192697a172 100644 --- a/code/game/objects/items/camping.dm +++ b/code/game/objects/items/camping.dm @@ -63,14 +63,14 @@ return var/mob/M = entering - var/atom/movable/renderer/roofs/roof_plane = M.GetRenderer(/atom/movable/renderer/roofs) + var/atom/movable/screen/plane_master/roof/roof_plane = M.hud_used?.plane_masters["[ROOF_PLANE]"] if(roof_plane) roof_plane.alpha = 76 /datum/large_structure/tent/mob_moved(mob/mover, turf/exit_point) . = ..() if(!.) - var/atom/movable/renderer/roofs/roof_plane = mover.GetRenderer(/atom/movable/renderer/roofs) + var/atom/movable/screen/plane_master/roof/roof_plane = mover.hud_used?.plane_masters["[ROOF_PLANE]"] if(roof_plane) roof_plane.alpha = 255 @@ -269,7 +269,7 @@ /obj/structure/component/tent_canvas/Destroy() //When we're destroyed, make sure we return the roof plane to anyone inside for(var/mob/M in loc) - var/atom/movable/renderer/roofs/roof_plane = M.GetRenderer(/atom/movable/renderer/roofs) + var/atom/movable/screen/plane_master/roof/roof_plane = M.hud_used?.plane_masters["[ROOF_PLANE]"] if(roof_plane) roof_plane.alpha = 255 return ..() diff --git a/code/game/objects/items/devices/slide_projector.dm b/code/game/objects/items/devices/slide_projector.dm index d499a996151..119df031516 100644 --- a/code/game/objects/items/devices/slide_projector.dm +++ b/code/game/objects/items/devices/slide_projector.dm @@ -144,7 +144,7 @@ icon_state = "white" anchored = TRUE simulated = FALSE - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE alpha = 100 var/datum/weakref/source @@ -163,7 +163,7 @@ return ClearOverlays() var/mutable_appearance/MA = new(I) - MA.plane = EFFECTS_ABOVE_LIGHTING_PLANE + MA.plane = ABOVE_LIGHTING_PLANE MA.appearance_flags = RESET_ALPHA MA.alpha = 170 MA.pixel_x = 0 diff --git a/code/game/objects/items/skrell.dm b/code/game/objects/items/skrell.dm index f468ba7013d..05132115faa 100644 --- a/code/game/objects/items/skrell.dm +++ b/code/game/objects/items/skrell.dm @@ -50,7 +50,7 @@ icon_state = "starprojection" mouse_opacity = TRUE duration = 30 SECONDS - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE light_power = 1 light_range = 1 light_color = LIGHT_COLOR_HALOGEN diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 4b4488c772f..8a675b8aa38 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -320,7 +320,7 @@ /obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks) var/image/welding_sparks = image('icons/effects/effects.dmi', welding_state) - welding_sparks.plane = EFFECTS_ABOVE_LIGHTING_PLANE + welding_sparks.plane = ABOVE_LIGHTING_PLANE target.AddOverlays(welding_sparks) . = ..() target.CutOverlays(welding_sparks) diff --git a/code/game/objects/structures/light_pole.dm b/code/game/objects/structures/light_pole.dm index bafcfdc13c2..33618c73166 100644 --- a/code/game/objects/structures/light_pole.dm +++ b/code/game/objects/structures/light_pole.dm @@ -58,7 +58,7 @@ /obj/effect/overlay/street_light icon = 'icons/obj/structure/urban/poles.dmi' icon_state = "street_light" - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE /obj/effect/overlay/street_light/classic icon_state = "classic_lamp_light" diff --git a/code/game/objects/structures/weapons_rack.dm b/code/game/objects/structures/weapons_rack.dm index 02a4726e1e8..2eaed49d684 100644 --- a/code/game/objects/structures/weapons_rack.dm +++ b/code/game/objects/structures/weapons_rack.dm @@ -159,7 +159,7 @@ transform_matrix.Translate((((world.icon_size/2)+BASE_OFFSET_RIFLE_SLOT) - world.icon_size) + (i*INTER_OFFSET_RIFLE_SLOT), 0) //Why not the rifle itself you might ask? Because there's the safety icon on it - var/mutable_appearance/weapon_appearance = mutable_appearance(G.icon, G.icon_state, plane = src.plane, flags = G.appearance_flags, layer = G.layer) + var/mutable_appearance/weapon_appearance = mutable_appearance(G.icon, G.icon_state, plane = src.plane, layer = G.layer) weapon_appearance.transform = transform_matrix visual_holder.overlays += weapon_appearance diff --git a/code/modules/atmospherics/components/unary/vent_pump.dm b/code/modules/atmospherics/components/unary/vent_pump.dm index 32964290b4e..2ba5fb08fc8 100644 --- a/code/modules/atmospherics/components/unary/vent_pump.dm +++ b/code/modules/atmospherics/components/unary/vent_pump.dm @@ -104,7 +104,7 @@ if(mapload) var/turf/T = loc var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.color = color I.alpha = 125 LAZYADD(T.blueprints, I) diff --git a/code/modules/atmospherics/components/unary/vent_scrubber.dm b/code/modules/atmospherics/components/unary/vent_scrubber.dm index 1992f40adb2..f8f766a1469 100644 --- a/code/modules/atmospherics/components/unary/vent_scrubber.dm +++ b/code/modules/atmospherics/components/unary/vent_scrubber.dm @@ -54,7 +54,7 @@ if(mapload) var/turf/T = loc var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.color = color I.alpha = 125 LAZYADD(T.blueprints, I) diff --git a/code/modules/atmospherics/pipes.dm b/code/modules/atmospherics/pipes.dm index feb10c1d9b4..998a50ff103 100644 --- a/code/modules/atmospherics/pipes.dm +++ b/code/modules/atmospherics/pipes.dm @@ -196,7 +196,7 @@ if(mapload) var/turf/T = loc var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.color = color I.alpha = 125 LAZYADD(T.blueprints, I) @@ -493,7 +493,7 @@ if(mapload) var/turf/T = loc var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.color = color I.alpha = 125 LAZYADD(T.blueprints, I) @@ -796,7 +796,7 @@ if(mapload) var/turf/T = loc var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.color = color I.alpha = 125 LAZYADD(T.blueprints, I) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 161c8d47a8f..0da68585394 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -311,7 +311,6 @@ GLOBAL_LIST_EMPTY_TYPED(preferences_datums, /datum/preferences) O.appearance = MA O.dir = D O.hud_layerise() - O.plane = 11 //THIS IS DUMB. Figure out a way to remove emissive blockers from the mob and their overlays. var/list/screen_locs = preview_screen_locs["[D]"] var/screen_x = screen_locs[1] var/screen_x_minor = screen_locs[2] diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 35b82e70473..0cda0fd85d6 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -1405,7 +1405,7 @@ icon = 'icons/obj/item/clothing/accessory/led_collar.dmi' icon_state = "led_collar" item_state = "led_collar" - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE contained_sprite = TRUE slot = ACCESSORY_SLOT_UTILITY_MINOR @@ -1423,6 +1423,6 @@ /obj/item/clothing/accessory/led_collar/get_accessory_mob_overlay(var/mob/living/carbon/human/H, var/force = FALSE) var/image/I = ..() - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.appearance_flags |= KEEP_APART return I diff --git a/code/modules/cooking/machinery/cooking_machines/microwave.dm b/code/modules/cooking/machinery/cooking_machines/microwave.dm index 197631bd2fe..d5cbc1946fe 100644 --- a/code/modules/cooking/machinery/cooking_machines/microwave.dm +++ b/code/modules/cooking/machinery/cooking_machines/microwave.dm @@ -221,7 +221,7 @@ if(operating) var/image/mwclosed_on = image(icon, "mw_on") if(!dirtiness) - mwclosed_on.plane = EFFECTS_ABOVE_LIGHTING_PLANE + mwclosed_on.plane = ABOVE_LIGHTING_PLANE AddOverlays(mwclosed_on) if(dirtiness) if(broken) diff --git a/code/modules/cooking/machinery/cooking_machines/oven.dm b/code/modules/cooking/machinery/cooking_machines/oven.dm index 3b5675e2f70..997b1702b2e 100644 --- a/code/modules/cooking/machinery/cooking_machines/oven.dm +++ b/code/modules/cooking/machinery/cooking_machines/oven.dm @@ -66,13 +66,13 @@ icon_state = door_closed if(!stat) var/image/ovenclosed_on = image('icons/obj/machinery/cooking_machines.dmi', door_closed_overlay) - ovenclosed_on.plane = EFFECTS_ABOVE_LIGHTING_PLANE + ovenclosed_on.plane = ABOVE_LIGHTING_PLANE AddOverlays(ovenclosed_on) else icon_state = door_open if(!stat) var/image/ovenopen_on = image('icons/obj/machinery/cooking_machines.dmi', door_open_overlay) - ovenopen_on.plane = EFFECTS_ABOVE_LIGHTING_PLANE + ovenopen_on.plane = ABOVE_LIGHTING_PLANE AddOverlays(ovenopen_on) ..() diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 403815a011e..91725f7ffc6 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -41,12 +41,12 @@ set_light(FALSE) return - var/mutable_appearance/screen_overlay = mutable_appearance(icon, "atm-active", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/screen_overlay = mutable_appearance(icon, "atm-active", plane = ABOVE_LIGHTING_PLANE) AddOverlays(screen_overlay) set_light(1.4, 1, COLOR_CYAN) if(held_card) - var/mutable_appearance/card_overlay = mutable_appearance(icon, "atm-cardin", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/card_overlay = mutable_appearance(icon, "atm-cardin", plane = ABOVE_LIGHTING_PLANE) AddOverlays(card_overlay) /obj/machinery/atm/process() diff --git a/code/modules/economy/OrderTerminal.dm b/code/modules/economy/OrderTerminal.dm index 8cf74c9dadb..23a468ca620 100644 --- a/code/modules/economy/OrderTerminal.dm +++ b/code/modules/economy/OrderTerminal.dm @@ -43,7 +43,7 @@ set_light(FALSE) return - var/mutable_appearance/screen_overlay = mutable_appearance(icon, "kitchenterminal-active", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/screen_overlay = mutable_appearance(icon, "kitchenterminal-active", plane = ABOVE_LIGHTING_PLANE) AddOverlays(screen_overlay) set_light(1.4, 1, COLOR_CYAN) diff --git a/code/modules/effects/particles/native_particles.dm b/code/modules/effects/particles/native_particles.dm index dc84dbe46ed..21816440dd5 100644 --- a/code/modules/effects/particles/native_particles.dm +++ b/code/modules/effects/particles/native_particles.dm @@ -82,63 +82,3 @@ layer = BELOW_TABLE_LAYER alpha = 128 - -//Spawner object -//Maybe we could pool them in and out - -/obj/particle_emitter - name = "" - anchored = TRUE - mouse_opacity = 0 - appearance_flags = PIXEL_SCALE - var/particle_type = null - - -/obj/particle_emitter/Initialize(mapload, time, _color) - . = ..() - if (particle_type) - particles = GLOB.all_particles[particle_type] - - if (time > 0) - QDEL_IN(src, time) - color = _color - -/obj/particle_emitter/heat - particle_type = "heat" - render_target = HEAT_EFFECT_TARGET - appearance_flags = PIXEL_SCALE | NO_CLIENT_COLOR - - -/obj/particle_emitter/heat/Initialize() - . = ..() - filters += filter(type = "blur", size = 1) - -/obj/particle_emitter/heat/high - particle_type = "high heat" - - -/obj/particle_emitter/mist - particle_type = "mist" - layer = FIRE_LAYER - -/obj/particle_emitter/mist/back - particle_type = "mist_back" - layer = BELOW_OBJ_LAYER - - -/obj/particle_emitter/mist/back/gas - render_target = COLD_EFFECT_BACK_TARGET - -/obj/particle_emitter/mist/back/gas/Initialize(mapload, time, _color) - . = ..() - filters += filter(type="alpha", render_source = COLD_EFFECT_TARGET, flags = MASK_INVERSE) - -//for cold gas effect -/obj/particle_emitter/mist/gas - render_target = COLD_EFFECT_TARGET - var/obj/particle_emitter/mist/back/b = /obj/particle_emitter/mist/back/gas - -/obj/particle_emitter/mist/gas/Initialize(mapload, time, _color) - . = ..() - b = new b(null) - vis_contents += b diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 5359662f75b..9f35bfb1728 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -43,7 +43,7 @@ /obj/machinery/mineral/processing_unit_console/Initialize(mapload, d, populate_components) . = ..() - var/mutable_appearance/screen_overlay = mutable_appearance(icon, "production_console-screen", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/screen_overlay = mutable_appearance(icon, "production_console-screen", plane = ABOVE_LIGHTING_PLANE) AddOverlays(screen_overlay) set_light(1.4, 1, COLOR_CYAN) diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 07d113e68c6..e4ae3a8bebd 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -19,7 +19,7 @@ /obj/machinery/mineral/stacking_unit_console/Initialize(mapload, d, populate_components) ..() - var/mutable_appearance/screen_overlay = mutable_appearance(icon, "production_console-screen", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/screen_overlay = mutable_appearance(icon, "production_console-screen", plane = ABOVE_LIGHTING_PLANE) AddOverlays(screen_overlay) set_light(1.4, 1, COLOR_CYAN) return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/mob/abstract/abstract.dm b/code/modules/mob/abstract/abstract.dm index 02f14102940..4009933ed91 100644 --- a/code/modules/mob/abstract/abstract.dm +++ b/code/modules/mob/abstract/abstract.dm @@ -3,6 +3,7 @@ status_flags = GODMODE invisibility = INVISIBILITY_ABSTRACT blocks_emissive = EMISSIVE_BLOCK_NONE + plane = GHOST_PLANE density = FALSE anchored = TRUE diff --git a/code/modules/mob/abstract/freelook/chunk.dm b/code/modules/mob/abstract/freelook/chunk.dm index c6a75bbd3f0..4c223ed552a 100644 --- a/code/modules/mob/abstract/freelook/chunk.dm +++ b/code/modules/mob/abstract/freelook/chunk.dm @@ -29,7 +29,7 @@ if(!obfuscation) obfuscation = image(icon, T, icon_state) obfuscation.layer = OBFUSCATION_LAYER - obfuscation.plane = DEFAULT_PLANE + obfuscation.plane = GAME_PLANE if(!obfuscation_underlay) // Creating a new icon of a fairly common icon state, adding some random color to prevent address searching, and hoping being static kills memory locality var/turf/floor = /turf/simulated/floor/tiled diff --git a/code/modules/mob/abstract/ghost/ghost.dm b/code/modules/mob/abstract/ghost/ghost.dm index 96189609d0e..adc8eb8c136 100644 --- a/code/modules/mob/abstract/ghost/ghost.dm +++ b/code/modules/mob/abstract/ghost/ghost.dm @@ -1,7 +1,5 @@ /mob/abstract/ghost stat = DEAD - layer = OBSERVER_LAYER - plane = OBSERVER_PLANE /// Toggle darkness. var/see_darkness = FALSE diff --git a/code/modules/mob/abstract/ghost/observer/observer.dm b/code/modules/mob/abstract/ghost/observer/observer.dm index 1dd148a39c7..aadc4fdd5ab 100644 --- a/code/modules/mob/abstract/ghost/observer/observer.dm +++ b/code/modules/mob/abstract/ghost/observer/observer.dm @@ -4,12 +4,12 @@ icon = 'icons/mob/mob.dmi' icon_state = "ghost" density = FALSE - canmove = 0 - blinded = 0 - anchored = 1 // don't get pushed around + canmove = FALSE + blinded = FALSE + anchored = TRUE // don't get pushed around invisibility = INVISIBILITY_OBSERVER simulated = FALSE - universal_speak = 1 + universal_speak = TRUE incorporeal_move = INCORPOREAL_GHOST mob_thinks = FALSE interaction_flags_atom = INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS @@ -17,7 +17,7 @@ /// If the ghost can re-enter their corpse. var/can_reenter_corpse /// The ghost's HUD datum. - var/datum/hud/hud = null + var/datum/hud/hud /// This variable is set to 1 when you enter the game as an observer. Remains null if you died in the game and are a ghost. Not reliable for admins; they change mobs a lot. var/started_as_observer /// If the ghost has enabled antagHUD. @@ -42,7 +42,7 @@ set_stat(DEAD) - ghostimage = image(src.icon,src,src.icon_state) + ghostimage = image(icon, src, icon_state) SSmobs.ghost_darkness_images |= ghostimage updateallghostimages() @@ -53,7 +53,7 @@ var/originaldesc = desc var/o_transform = transform - appearance = body + set_appearance(body) appearance_flags = KEEP_TOGETHER desc = originaldesc transform = o_transform @@ -609,6 +609,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if (ghostimage) client.images -= ghostimage //remove ourself +/** + * We use this proc to set appearance because doing so resets the plane. + * We want the plane to stay at GHOST_PLANE to avoid weird overlaying stuff. + */ +/mob/abstract/ghost/observer/proc/set_appearance(new_appearance) + appearance = new_appearance + plane = GHOST_PLANE + /mob/abstract/ghost/observer/MayRespawn(var/feedback = 0, var/respawn_type = null) if(!client) return 0 diff --git a/code/modules/mob/abstract/ghost/storyteller/storyteller.dm b/code/modules/mob/abstract/ghost/storyteller/storyteller.dm index 9355913a73d..1926bf58498 100644 --- a/code/modules/mob/abstract/ghost/storyteller/storyteller.dm +++ b/code/modules/mob/abstract/ghost/storyteller/storyteller.dm @@ -6,7 +6,6 @@ status_flags = GODMODE invisibility = INVISIBILITY_OBSERVER see_invisible = SEE_INVISIBLE_OBSERVER - layer = OBSERVER_LAYER incorporeal_move = INCORPOREAL_GHOST simulated = FALSE diff --git a/code/modules/mob/abstract/new_player/menu.dm b/code/modules/mob/abstract/new_player/menu.dm index db76ca2cbae..fe1353e011d 100644 --- a/code/modules/mob/abstract/new_player/menu.dm +++ b/code/modules/mob/abstract/new_player/menu.dm @@ -341,7 +341,7 @@ ABSTRACT_TYPE(/atom/movable/screen/new_player/selection) announce_ghost_joinleave(src) var/mob/living/carbon/human/dummy/mannequin/mannequin = new client.prefs.dress_preview_mob(mannequin) - observer.appearance = mannequin.appearance + observer.set_appearance(mannequin.appearance) observer.appearance_flags = KEEP_TOGETHER observer.alpha = 127 observer.layer = initial(observer.layer) diff --git a/code/modules/mob/living/carbon/slime/slime_extractor.dm b/code/modules/mob/living/carbon/slime/slime_extractor.dm index b236fac7b88..86f20263730 100644 --- a/code/modules/mob/living/carbon/slime/slime_extractor.dm +++ b/code/modules/mob/living/carbon/slime/slime_extractor.dm @@ -39,9 +39,9 @@ var/mutable_appearance/panel_overlay = mutable_appearance(icon, "[icon_state]-panel") AddOverlays(panel_overlay) if(length(extract_slimes)) - var/mutable_appearance/interior_overlay = mutable_appearance(icon, "[icon_state]-interior", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/interior_overlay = mutable_appearance(icon, "[icon_state]-interior", plane = ABOVE_LIGHTING_PLANE) AddOverlays(interior_overlay) - var/mutable_appearance/spinning_overlay = mutable_appearance(icon, "[icon_state]-running", plane = EFFECTS_ABOVE_LIGHTING_PLANE) + var/mutable_appearance/spinning_overlay = mutable_appearance(icon, "[icon_state]-running", plane = ABOVE_LIGHTING_PLANE) AddOverlays(spinning_overlay) set_light(2.5, 1, COLOR_VIOLET) else diff --git a/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm b/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm index b101c8becd0..1c81dfe06c3 100644 --- a/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm @@ -123,7 +123,7 @@ /mob/living/simple_animal/construct/proc/add_glow() ClearOverlays() - var/overlay_plane = EFFECTS_ABOVE_LIGHTING_PLANE + var/overlay_plane = ABOVE_LIGHTING_PLANE var/image/glow = image(icon, "glow-[icon_state]") glow.plane = overlay_plane diff --git a/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm b/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm index 73865532b5c..b14a263ff48 100644 --- a/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm @@ -29,7 +29,7 @@ . = ..() name = "[initial(name)] ([rand(100, 999)])" eye_overlay = image(icon, "[icon_state]-eyes_emag") - eye_overlay.plane = EFFECTS_ABOVE_LIGHTING_PLANE + eye_overlay.plane = ABOVE_LIGHTING_PLANE eye_overlay.appearance_flags = KEEP_APART AddOverlays(eye_overlay) diff --git a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm index a8438c37aee..7fdc843352f 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm @@ -187,7 +187,7 @@ /mob/living/simple_animal/hostile/carp/shark/reaver/eel/Initialize() . = ..() eye_overlay = image(icon, "eel_eyeglow") - eye_overlay.plane = EFFECTS_ABOVE_LIGHTING_PLANE + eye_overlay.plane = ABOVE_LIGHTING_PLANE eye_overlay.appearance_flags = KEEP_APART AddOverlays(eye_overlay) set_light(MINIMUM_USEFUL_LIGHT_RANGE, 2, LIGHT_COLOR_TUNGSTEN) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 08deb11c8a1..a9af1fceff6 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -100,7 +100,6 @@ clear_important_client_contents() enable_client_mobs_in_contents() - AddDefaultRenderers() update_client_color() add_click_catcher() diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 6de5c80239e..d63394c3b8b 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -10,7 +10,6 @@ disconnect_time = world.realtime log_access("Logout: [key_name(src)]") SSstatistics.update_status() - ClearRenderers() clear_important_client_contents() my_client = null diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index d21ba0bfb83..169ef9a5172 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -62,7 +62,7 @@ desc = DESC_PARENT icon = 'icons/effects/lighting_overlay.dmi' icon_state = "dark" - plane = OPENTURF_MAX_PLANE + plane = OPEN_SPACE_PLANE_END layer = MIMICED_LIGHTING_LAYER // blend_mode = BLEND_MULTIPLY color = "#00000033" @@ -77,7 +77,7 @@ /atom/movable/openspace/multiplier/proc/copy_lighting(atom/movable/lighting_overlay/LO) appearance = LO layer = MIMICED_LIGHTING_LAYER - plane = OPENTURF_MAX_PLANE + plane = OPEN_SPACE_PLANE_END set_invisibility(0) if (icon_state == null) blend_mode = BLEND_MULTIPLY @@ -120,7 +120,7 @@ // Object used to hold a mimiced atom's appearance. /atom/movable/openspace/mimic - plane = OPENTURF_MAX_PLANE + plane = OPEN_SPACE_PLANE_END var/atom/movable/associated_atom var/depth var/queued = 0 @@ -174,7 +174,7 @@ // This thing holds the mimic appearance for non-OVERWRITE turfs. /atom/movable/openspace/turf_proxy - plane = OPENTURF_MAX_PLANE + 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. @@ -196,7 +196,7 @@ // A type for copying non-overwrite turfs' self-appearance. /atom/movable/openspace/turf_mimic - plane = OPENTURF_MAX_PLANE // These *should* only ever be at the top? + plane = OPEN_SPACE_PLANE_END // These *should* only ever be at the top? mouse_opacity = MOUSE_OPACITY_TRANSPARENT var/turf/delegate diff --git a/code/modules/organs/subtypes/unbreakable.dm b/code/modules/organs/subtypes/unbreakable.dm index 70e62b70101..e1067e3b249 100644 --- a/code/modules/organs/subtypes/unbreakable.dm +++ b/code/modules/organs/subtypes/unbreakable.dm @@ -45,6 +45,6 @@ /obj/item/organ/external/head/unbreakable/revenant/get_additional_images(var/mob/living/carbon/human/H) var/image/return_image = image(H.species.eyes_icons, H, "[H.species.eyes]_glow") - return_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + return_image.plane = ABOVE_LIGHTING_PLANE return_image.appearance_flags = KEEP_APART return list(return_image) diff --git a/code/modules/overmap/exoplanets/decor/objs/monolith.dm b/code/modules/overmap/exoplanets/decor/objs/monolith.dm index aa3d406e1cd..f7b8e6c8349 100644 --- a/code/modules/overmap/exoplanets/decor/objs/monolith.dm +++ b/code/modules/overmap/exoplanets/decor/objs/monolith.dm @@ -22,7 +22,7 @@ var/image/I = image(icon,"[icon_state]decor") I.appearance_flags = RESET_COLOR I.color = get_random_colour(0, 150, 255) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE AddOverlays(I) set_light(0.3, 0.1, 2, l_color = I.color) diff --git a/code/modules/overmap/overmap_object.dm b/code/modules/overmap/overmap_object.dm index 5271e962c12..7d16c16043f 100644 --- a/code/modules/overmap/overmap_object.dm +++ b/code/modules/overmap/overmap_object.dm @@ -106,7 +106,7 @@ return INITIALIZE_HINT_QDEL if(known) - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE for(var/obj/machinery/computer/ship/helm/H in SSmachinery.machinery) H.get_known_sectors() update_icon() diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 3cec86a9658..ef2e2379104 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -107,7 +107,7 @@ By design, d1 is the smallest direction and d2 is the highest if(mapload) var/image/I = image(icon, T, icon_state, dir, pixel_x, pixel_y) - I.plane = EFFECTS_ABOVE_LIGHTING_PLANE + I.plane = ABOVE_LIGHTING_PLANE I.alpha = 125 I.color = color LAZYADD(T.blueprints, I) diff --git a/code/modules/power/radial_floodlight.dm b/code/modules/power/radial_floodlight.dm index 81c89877c91..46dbe7b4ab8 100644 --- a/code/modules/power/radial_floodlight.dm +++ b/code/modules/power/radial_floodlight.dm @@ -63,5 +63,5 @@ ClearOverlays() if(on) var/image/light = image(icon, src, "[icon_state]-light") - light.plane = EFFECTS_ABOVE_LIGHTING_PLANE + light.plane = ABOVE_LIGHTING_PLANE AddOverlays(light) diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index a60f1480fb9..5fdd847c9f2 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -53,7 +53,7 @@ field_generator power level display if(state == 2) AddOverlays("+welding") var/image/lights_image = image(icon, null, "+lights") - lights_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + lights_image.plane = ABOVE_LIGHTING_PLANE AddOverlays(lights_image) /obj/machinery/field_generator/process() diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index c870baafed2..3f9db36c98c 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -15,7 +15,7 @@ if(anchored) AddOverlays("[icon_state]+bolts") var/image/lights_image = image(icon, null, "[icon_state]+lights") - lights_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + lights_image.plane = ABOVE_LIGHTING_PLANE AddOverlays(lights_image) /obj/machinery/the_singularitygen/process() diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index fca802887a9..106b4e2046b 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -18,7 +18,7 @@ if(anchored) AddOverlays("[icon_state]+bolts") var/image/lights_image = image(icon, null, "[icon_state]+lights") - lights_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + lights_image.plane = ABOVE_LIGHTING_PLANE AddOverlays(lights_image) /obj/machinery/power/tesla_coil/RefreshParts() @@ -79,7 +79,7 @@ if(anchored) AddOverlays("[icon_state]+bolts") var/image/lights_image = image(icon, null, "[icon_state]+lights") - lights_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + lights_image.plane = ABOVE_LIGHTING_PLANE AddOverlays(lights_image) /obj/machinery/power/grounding_rod/attackby(obj/item/attacking_item, mob/user) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 8f3c79ff64d..940fda6895f 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -17,7 +17,7 @@ dissipate = 1 dissipate_delay = 10 dissipate_strength = 1 - plane = EFFECTS_ABOVE_LIGHTING_PLANE + plane = ABOVE_LIGHTING_PLANE blend_mode = BLEND_ADD var/failed_direction = 0 var/list/orbiting_balls = list() diff --git a/code/_onclick/hud/rendering/_render_readme.md b/code/modules/rendering/_render_readme.md similarity index 80% rename from code/_onclick/hud/rendering/_render_readme.md rename to code/modules/rendering/_render_readme.md index 3f1cd6c99af..4894f823be6 100644 --- a/code/_onclick/hud/rendering/_render_readme.md +++ b/code/modules/rendering/_render_readme.md @@ -8,9 +8,13 @@ ## Byond internal functionality This part of the guide will assume that you have read the byond reference entry for rendering at www.byond.com/docs/ref//#/{notes}/renderer -When you create an atom, this will always create an internal byond structure called an "appearance". This appearance you will likely be familiar with, as it is exposed through the /atom/var/appearance var. This appearance var holds data on how to render the object, ie what icon/icon_state/color etc it is using. Note that appearance vars will always copy, and do not hold a reference. When you update a var, for example lets pretend we add a filter, the appearance will be updated to include the filter. Note that, however, vis_contents objets are uniquely excluded from appearances. Then, when the filter is updated, the appearance will be recreated, and the atom marked as "dirty". After it has been updated, the SendMaps() function (sometimes also called maptick), which is a internal byond function that iterates over all objects in a clients view and in the clients.mob.contents, checks for "dirty" atoms, then resends any "dirty" appearances to clients as needed and unmarks them as dirty. This function is notoriosly slow, but we can see it's tick usage through the world.map_cpu var. We can also avoid more complex checks checking whether an object is visible on a clients screen by using the TILE_BOUND appearance flag. +When you create an atom, this will always create an internal byond structure called an "appearance". This appearance you will likely be familiar with, as it is exposed through the /atom/var/appearance var. This appearance var holds data on how to render the object, ie what icon/icon_state/color etc it is using. Note that appearance vars will always copy, and do not hold a reference. When you update a var, for example let's pretend we add a filter, the appearance will be updated to include the filter. Note that, however, vis_contents objets are uniquely excluded from appearances. Then, when the filter is updated, the appearance will be recreated, and the atom marked as "dirty". After it has been updated, the SendMaps() function (sometimes also called maptick), which is an internal byond function that iterates over all objects in a client's view and in the clients.mob.contents, checks for "dirty" atoms, then resends any "dirty" appearances to clients as needed and unmarks them as dirty. This function is notoriously slow, but we can see its tick usage through the world.map_cpu var. We can also avoid more complex checks checking whether an object is visible on a client's screen by using the TILE_BOUND appearance flag. -Finally, we arrive at clientside behavior, where we have two main clientside functions: GetMapIcons, and Render. GetMapIcons is repsonsible for actual rendering calculations on the clientside, such as "Group Icons and Set bounds", which performs clientside calculations for transform matrixes. Note that particles here are handled in a seperate thread and are not diplayed in the clientside profiler. Render handles the actual drawing of the screen. +Finally, we arrive at clientside behavior, where we have two main clientside functions: GetMapIcons, and Render. GetMapIcons is repsonsible for actual rendering calculations on the clientside, such as "Group Icons and Set bounds", which performs clientside calculations for transform matrixes. Note that particles here are handled in a separate thread and are not diplayed in the clientside profiler. Render handles the actual drawing of the screen. + +For debugging rendering issues its reccomended you do two things: +A) Talk to someone who has inside knowledge(like lummox) about it, most of this is undocumented and bugs often +B) Use the undocumented debug printer which reads of data on icons rendering, this is very dense but can be useful in some cases. To use: Right click top tab -> Options & Messages -> Client -> Command -> Enter ".debug profile mapicons" and press Enter -> go to your Byond directory and find BYOND/cfg/mapicons.json . Yes this is one giant one-line json. ## Known internal snowflake The following is an incomplete list of pitfalls that come from byond snowflake that are known, this list is obviously incomplete. @@ -25,6 +29,7 @@ The following is an incomplete list of pitfalls that come from byond snowflake t 8. Byond uses DirectX 9 (Lummox said he wants to update to DirectX 11) 9. Particles are just fancy overlays and are not independent of their owner 10. Maptick items inside mob.contents are cheaper compared to most other movables +11. Displacement filter: The byond "displacement filter" does not, as the name would make you expect, use displacement maps, but instead uses normal maps. ## The rendering solution One of the main issues with making pretty effects is how objects can only render to one plane, and how filters can only be applied to single objects. Quite simply it means we cant apply effects to multiple planes at once, and an effect to one plane only by treating it as a single unit: @@ -50,13 +55,3 @@ The rendering system uses two objects to unify planes: render_relay and render_p Goodluck and godspeed with coding - Just another contributor - -## Baystation/Aurorastation Differences - -The bay implementation differs in some points but you can treat the prior sections as broadly accurate. - -- Locally we have refactored and simplified the above concepts down to `/atom/movable/renderer` and undifferentiated relay movables. -- There is no type destinction between renderers intended to draw normal entities and renderers intended to draw other renderers. -- We instead refer to these as "Plane Renderers" and "Group Renderers", and note that Group Renderers may render *other* Group Renderers in turn. -- We additionally add the extra "Effect Renderer" as a distinct concept. Effect renderers are more virtual, and drawn to other renderers by filters instead. -- See the comments in _renderer.dm for detail next to code. \ No newline at end of file diff --git a/code/modules/rendering/plane_master.dm b/code/modules/rendering/plane_master.dm new file mode 100644 index 00000000000..e1b27036501 --- /dev/null +++ b/code/modules/rendering/plane_master.dm @@ -0,0 +1,182 @@ +/atom/movable/screen/plane_master + screen_loc = "CENTER" + icon_state = "blank" + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + blend_mode = BLEND_OVERLAY + plane = LOWEST_EVER_PLANE + var/show_alpha = 255 + var/hide_alpha = 0 + + //--rendering relay vars-- + ///integer: what plane we will relay this planes render to + var/render_relay_plane = RENDER_PLANE_GAME + ///bool: Whether this plane should get a render target automatically generated + var/generate_render_target = TRUE + ///integer: blend mode to apply to the render relay in case you dont want to use the plane_masters blend_mode + var/blend_mode_override + ///reference: current relay this plane is utilizing to render + var/obj/render_plane_relay/relay + +/atom/movable/screen/plane_master/proc/Show(override) + alpha = override || show_alpha + +/atom/movable/screen/plane_master/proc/Hide(override) + alpha = override || hide_alpha + +//Why do plane masters need a backdrop sometimes? Read https://secure.byond.com/forum/?post=2141928 +//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. +/atom/movable/screen/plane_master/proc/backdrop(mob/mymob) + SHOULD_CALL_PARENT(TRUE) + if(!isnull(render_relay_plane)) + relay_render_to_plane(mymob, render_relay_plane) + +///Contains most things in the game world +/atom/movable/screen/plane_master/game_world + name = "game world plane master" + plane = GAME_PLANE + blend_mode = BLEND_OVERLAY + +/atom/movable/screen/plane_master/rendering_plate/game_world/Initialize(mapload, datum/hud/hud_owner) + . = ..() + add_filter("displacer", 1, displacement_map_filter(render_source = DISPLACEMENT_PLATE_RENDER_TARGET, size = 10)) + +/atom/movable/screen/plane_master/game_world_above + name = "above game world plane master" + plane = ABOVE_GAME_PLANE + +/atom/movable/screen/plane_master/ghost + name = "ghost plane master" + plane = GHOST_PLANE + render_relay_plane = RENDER_PLANE_NON_GAME + +/// Plane master handling display of building roofs. They're meant to become invisible when inside a building. +/atom/movable/screen/plane_master/roof + name = "roof plane master" + plane = ROOF_PLANE + appearance_flags = PLANE_MASTER + blend_mode = BLEND_OVERLAY + +/atom/movable/screen/plane_master/space + name = "space plane master" + plane = SPACE_PLANE + blend_mode = BLEND_OVERLAY + +/// Plane master handling skyboxes. +/atom/movable/screen/plane_master/skybox + name = "skybox plane master" + plane = SKYBOX_PLANE + blend_mode = BLEND_MULTIPLY + appearance_flags = PLANE_MASTER + +/** + * Plane master handling byond internal blackness + * vars are set as to replicate behavior when rendering to other planes + * do not touch this unless you know what you are doing + */ +/atom/movable/screen/plane_master/blackness + name = "darkness plane master" + plane = BLACKNESS_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + blend_mode = BLEND_MULTIPLY + appearance_flags = PLANE_MASTER | NO_CLIENT_COLOR | PIXEL_SCALE +//byond internal end + +/*! + * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. + * + * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color. + * Emissive blockers are pasted with an atom color that converts them to be entirely some different color. + * Emissive overlays and emissive blockers are put onto the same plane. + * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects. + * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is. + * This is then used to alpha mask the lighting plane. + */ + +///Contains all lighting objects +/atom/movable/screen/plane_master/lighting + name = "lighting plane master" + plane = LIGHTING_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + blend_mode = BLEND_MULTIPLY + +/atom/movable/screen/plane_master/lighting/Initialize() + . = ..() + add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE)) + +/** + * Handles emissive overlays and emissive blockers. + */ +/atom/movable/screen/plane_master/emissive + name = "emissive plane master" + plane = EMISSIVE_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = EMISSIVE_RENDER_TARGET + render_relay_plane = null + +/atom/movable/screen/plane_master/emissive/Initialize() + . = ..() + add_filter("em_block_masking", 1, color_matrix_filter(GLOB.em_mask_matrix)) + +/atom/movable/screen/plane_master/above_lighting + name = "above lighting plane master" + plane = ABOVE_LIGHTING_PLANE + render_relay_plane = RENDER_PLANE_GAME + +/atom/movable/screen/plane_master/runechat + name = "runechat plane master" + plane = RUNECHAT_PLANE + appearance_flags = PLANE_MASTER + blend_mode = BLEND_OVERLAY + render_relay_plane = RENDER_PLANE_NON_GAME + +/atom/movable/screen/plane_master/runechat/backdrop(mob/mymob) + . = ..() + remove_filter("AO") + add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) + +/atom/movable/screen/plane_master/fullscreen + name = "fullscreen alert plane" + plane = FULLSCREEN_PLANE + render_relay_plane = RENDER_PLANE_NON_GAME + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/atom/movable/screen/plane_master/hud + name = "HUD plane" + plane = HUD_PLANE + render_relay_plane = RENDER_PLANE_NON_GAME + +/atom/movable/screen/plane_master/cinematic + name = "cinematic plane" + plane = CINEMATIC_PLANE + render_relay_plane = RENDER_PLANE_NON_GAME + +/atom/movable/screen/plane_master/displacement + name = "displacement plane" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = DISPLACEMENT_PLATE_RENDER_LAYER + render_target = DISPLACEMENT_PLATE_RENDER_TARGET + render_relay_plane = null + +/atom/movable/screen/plane_master/open_space + name = "open space plane" + plane = OPEN_SPACE_PLANE_END //aurora snowflake: our openspace system works bottom up, not top down like CM's + +/atom/movable/screen/plane_master/open_space/Initialize(mapload, offset) + name = "open space plane [offset]" + plane -= offset + . = ..() + add_filter("multizblur", 1, gauss_blur_filter(0.5 + 0.25 * (offset + 1))) + +/atom/movable/screen/plane_master/openspace_backdrop + name = "open space plane master" + plane = OPENSPACE_BACKDROP_PLANE + appearance_flags = PLANE_MASTER + blend_mode = BLEND_MULTIPLY + alpha = 255 + +/atom/movable/screen/plane_master/openspace_backdrop/Initialize() + . = ..() + filters = list() + filters += filter(type = "drop_shadow", color = "#04080FAA", size = -10) + filters += filter(type = "drop_shadow", color = "#04080FAA", size = -15) + filters += filter(type = "drop_shadow", color = "#04080FAA", size = -20) diff --git a/code/modules/rendering/plane_master_controller.dm b/code/modules/rendering/plane_master_controller.dm new file mode 100644 index 00000000000..61155803d80 --- /dev/null +++ b/code/modules/rendering/plane_master_controller.dm @@ -0,0 +1,76 @@ +///Atom that manages and controls multiple planes. It's an atom so we can hook into add_filter etc. Multiple controllers can control one plane. +/atom/movable/plane_master_controller + ///List of planes in this controllers control. Initially this is a normal list, but becomes an assoc list of plane numbers as strings | plane instance + var/list/controlled_planes = list() + ///hud that owns this controller + var/datum/hud/owner_hud + +INITIALIZE_IMMEDIATE(/atom/movable/plane_master_controller) + +///Ensures that all the planes are correctly in the controlled_planes list. +/atom/movable/plane_master_controller/Initialize(mapload, datum/hud/hud) + . = ..() + if(!istype(hud)) + return + + owner_hud = hud + var/assoc_controlled_planes = list() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/instance = owner_hud.plane_masters["[i]"] + if(!instance) //If we looked for a hud that isn't instanced, just keep going + stack_trace("[i] isn't a valid plane master layer for [owner_hud.type], are you sure it exists in the first place?") + continue + assoc_controlled_planes["[i]"] = instance + controlled_planes = assoc_controlled_planes + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_filter(name, priority, list/params) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.add_filter(name, priority, params) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/remove_filter(name_or_names) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.remove_filter(name_or_names) + +/atom/movable/plane_master_controller/update_filters() + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.update_filters() + +///Gets all filters for this controllers plane masters +/atom/movable/plane_master_controller/proc/get_filters(name) + . = list() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + . += pm_iterator.get_filter(name) + +///Transitions all filters owned by this plane master controller +/atom/movable/plane_master_controller/transition_filter(name, list/new_params, time, easing, loop) + . = ..() + for(var/i in controlled_planes) + var/atom/movable/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.transition_filter(name, new_params, time, easing, loop) + +/atom/movable/plane_master_controller/game + name = PLANE_MASTERS_GAME + controlled_planes = list( + SPACE_PLANE, + SKYBOX_PLANE, + GAME_PLANE, + LIGHTING_PLANE + ) + +/// Exists for convienience when referencing all non-master render plates. +/// This is the whole game and the UI, but not the escape menu. +/atom/movable/plane_master_controller/non_master + name = PLANE_MASTERS_NON_MASTER + controlled_planes = list( + RENDER_PLANE_GAME, + RENDER_PLANE_NON_GAME, + ) diff --git a/code/modules/rendering/render_plate.dm b/code/modules/rendering/render_plate.dm new file mode 100644 index 00000000000..15cfa96c268 --- /dev/null +++ b/code/modules/rendering/render_plate.dm @@ -0,0 +1,79 @@ +/*! + * Custom rendering solution to allow for advanced effects + * We (ab)use plane masters and render source/target to cheaply render 2+ planes as 1 + * if you want to read more read the _render_readme.md + */ + +/** + * Render relay object assigned to a plane master to be able to relay it's render onto other planes that are not it's own + */ +/obj/render_plane_relay + screen_loc = "1,1" + layer = -1 + plane = 0 + appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER + +/** + * ## Rendering plate + * + * Acts like a plane master, but for plane masters + * Renders other planes onto this plane, through the use of render objects + * Any effects applied onto this plane will act on the unified plane + * IE a bulge filter will apply as if the world was one object + * remember that once planes are unified on a render plate you cant change the layering of them! + */ +/atom/movable/screen/plane_master/rendering_plate + name = "default rendering plate" + + +///this plate renders the final screen to show to the player +/atom/movable/screen/plane_master/rendering_plate/master + name = "master rendering plate" + plane = RENDER_PLANE_MASTER + render_relay_plane = null + generate_render_target = FALSE + +///renders general in charachter game objects +/atom/movable/screen/plane_master/rendering_plate/game_world + name = "game rendering plate" + plane = RENDER_PLANE_GAME + render_relay_plane = RENDER_PLANE_MASTER + +///render plate for OOC stuff like ghosts, hud-screen effects, etc +/atom/movable/screen/plane_master/rendering_plate/non_game + name = "non-game rendering plate" + plane = RENDER_PLANE_NON_GAME + render_relay_plane = RENDER_PLANE_MASTER + +/** + * Plane master proc called in backdrop() that creates a relay object, sets it as needed and then adds it to the clients screen + * Sets: + * * layer from plane to avoid z-fighting + * * plane to relay the render to + * * render_source so that the plane will render on this object + * * mouse opacity to ensure proper mouse hit tracking + * * name for debugging purposes + * Other vars such as alpha will automatically be applied with the render source + * Arguments: + * * mymob: mob whose plane is being backdropped + * * relay_plane: plane we are relaying this plane master to + */ +/atom/movable/screen/plane_master/proc/relay_render_to_plane(mob/mymob, relay_plane) + if(relay in mymob.client.screen) //backdrop can be called multiple times + return + if(!render_target && generate_render_target) + render_target = "*[name]: AUTOGENERATED RENDER TGT" + relay = new() + relay.render_source = render_target + relay.plane = relay_plane + relay.layer = (plane + abs(LOWEST_EVER_PLANE))*0.5 //layer must be positive but can be a decimal + + if(blend_mode_override) + relay.blend_mode = blend_mode_override + else + relay.blend_mode = blend_mode + relay.mouse_opacity = mouse_opacity + relay.name = render_target + mymob.client.add_to_screen(relay) + if(blend_mode != BLEND_MULTIPLY) + blend_mode = BLEND_DEFAULT diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 78b6f7a7b63..08e62ab241e 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -35,7 +35,7 @@ var/motherdock //tag of mothershuttle landmark, defaults to starting location var/squishes = TRUE //decides whether or not things get squished when it moves. - var/cargo_elevator = FALSE // Snowflake variable for the cargo elevator. Decides whether you will take fall damage or not. + var/cargo_elevator = FALSE // Snowflake variable for the cargo elevator. Decides whether you will take fall damage or not /datum/shuttle/New(_name, var/obj/effect/shuttle_landmark/initial_location) ..() diff --git a/code/modules/shuttles/shuttle_supply.dm b/code/modules/shuttles/shuttle_supply.dm index 4a0d4150179..6d646b3f759 100644 --- a/code/modules/shuttles/shuttle_supply.dm +++ b/code/modules/shuttles/shuttle_supply.dm @@ -42,7 +42,9 @@ addtimer(CALLBACK(src, PROC_REF(prepare_elevator)), 1 MINUTE) // pseudo initialize. We give mapload some time before initializing rest of the properties /datum/shuttle/autodock/ferry/supply/proc/prepare_elevator() - var/obj/dest_helper = locate(/obj/effect/landmark/destination_helper/cargo_elevator) + var/obj/dest_helper = SSshuttle.cargo_dest_helper + if(!dest_helper) + crash_with("No cargo destination helper found for the elevator!") target_dest_x = dest_helper.x target_dest_y = dest_helper.y target_dest_z = dest_helper.z @@ -239,6 +241,21 @@ /obj/effect/landmark/destination_helper/cargo_elevator name = "cargo elevator destination helper" +/obj/effect/landmark/destination_helper/cargo_elevator/Initialize(mapload) + ..() + return INITIALIZE_HINT_LATELOAD + +/obj/effect/landmark/destination_helper/cargo_elevator/LateInitialize() + . = ..() + if(SSshuttle.cargo_dest_helper) + log_and_message_admins("Multiple cargo destination helpers detected; overriding.") + SSshuttle.cargo_dest_helper = src + +/obj/effect/landmark/destination_helper/cargo_elevator/Destroy() + if(SSshuttle.cargo_dest_helper == src) + SSshuttle.cargo_dest_helper = null + return ..() + /obj/effect/step_trigger/cargo_elevator name = "cargo elevator shaft" icon = 'icons/effects/map_effects.dmi' diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 3ccf0c44b7b..182a999c8a1 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -222,13 +222,13 @@ GLOBAL_LIST_INIT(can_enter_vent_with, list( for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) // Adds pipe and manifold images if(!A.pipe_image) A.pipe_image = image(A, A.loc, dir = A.dir) - A.pipe_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + A.pipe_image.plane = ABOVE_LIGHTING_PLANE pipes_shown += A.pipe_image client.images += A.pipe_image for (var/obj/machinery/atmospherics/V in network.normal_members) // Adds vent and scrubber images if (!V.pipe_image || istype(V, /obj/machinery/atmospherics/unary/vent_pump/)) V.pipe_image = image(V, V.loc, dir = V.dir) - V.pipe_image.plane = EFFECTS_ABOVE_LIGHTING_PLANE + V.pipe_image.plane = ABOVE_LIGHTING_PLANE pipes_shown += V.pipe_image client.images += V.pipe_image diff --git a/code/modules/weather/_weather.dm b/code/modules/weather/_weather.dm index 60ef4a5c50d..6e4f9442339 100644 --- a/code/modules/weather/_weather.dm +++ b/code/modules/weather/_weather.dm @@ -23,7 +23,7 @@ */ /obj/abstract/weather_system - plane = DEFAULT_PLANE + plane = GAME_PLANE layer = ABOVE_PROJECTILE_LAYER icon = 'icons/effects/weather.dmi' icon_state = "blank" @@ -119,7 +119,7 @@ // Dummy object for lightning flash animation. /obj/abstract/lightning_overlay - plane = EFFECTS_ABOVE_LIGHTING_PLANE //Future EMISSIVE_PLANE + plane = ABOVE_LIGHTING_PLANE //Future EMISSIVE_PLANE layer = LIGHTNING_LAYER icon = 'icons/effects/weather.dmi' icon_state = "full" diff --git a/code/modules/xgm/xgm_gas_data.dm b/code/modules/xgm/xgm_gas_data.dm index 9ba6c0d8632..d8d932bb5f5 100644 --- a/code/modules/xgm/xgm_gas_data.dm +++ b/code/modules/xgm/xgm_gas_data.dm @@ -79,7 +79,6 @@ var/global/datum/xgm_gas_data/gas_data desc = "You shouldn't be clicking this." plane = HEAT_EFFECT_PLANE gas_id = GAS_HEAT - render_source = HEAT_EFFECT_TARGET /obj/gas_overlay/heat/Initialize(mapload, gas) . = ..() @@ -87,15 +86,13 @@ var/global/datum/xgm_gas_data/gas_data icon_state = null /obj/effect/gas_cold_back - render_source = COLD_EFFECT_BACK_TARGET - plane = DEFAULT_PLANE + plane = GAME_PLANE layer = BELOW_OBJ_LAYER /obj/gas_overlay/cold name = "gas" desc = "You shouldn't be clicking this." gas_id = GAS_COLD - render_source = COLD_EFFECT_TARGET var/obj/effect/gas_cold_back/b = null /obj/gas_overlay/cold/Initialize(mapload, gas) diff --git a/html/changelogs/mattatlas-fallingapart.yml b/html/changelogs/mattatlas-fallingapart.yml new file mode 100644 index 00000000000..dd427f12ddc --- /dev/null +++ b/html/changelogs/mattatlas-fallingapart.yml @@ -0,0 +1,60 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: MattAtlas (porting), CM and /tg/ coders (original code) + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - experiment: "Replaced our renderer system with TG and CM's planemasters." + - rscadd: "Open space now has a gaussian blur filter." + - bugfix: "Fixed esoteric smoothing behaviour that was a bug for a long time; lattices should no longer smooth with nothing." diff --git a/icons/effects/shockwave.dmi b/icons/effects/shockwave.dmi new file mode 100644 index 00000000000..c22acfa1d59 Binary files /dev/null and b/icons/effects/shockwave.dmi differ