Rendering refactor P1: Plane unification and render relaying (pictures and video included) (#8479)

Co-authored-by: TiviPlus <57223640+TiviPlus@users.noreply.github.com>
This commit is contained in:
SkyratBot
2021-10-01 01:08:39 +02:00
committed by GitHub
parent 2462ff8d4a
commit 6a3a1aed83
17 changed files with 289 additions and 99 deletions

View File

@@ -1,34 +1,28 @@
//Defines for atom layers and planes
//KEEP THESE IN A NICE ACSCENDING ORDER, PLEASE
//NEVER HAVE ANYTHING BELOW THIS PLANE ADJUST IF YOU NEED MORE SPACE
#define LOWEST_EVER_PLANE -200
#define CLICKCATCHER_PLANE -99
#define PLANE_SPACE -95
#define PLANE_SPACE_RENDER_TARGET "PLANE_SPACE"
#define PLANE_SPACE_PARALLAX -90
#define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX"
#define GRAVITY_PULSE_PLANE -11
#define GRAVITY_PULSE_RENDER_TARGET "*GRAVPULSE_RENDER_TARGET"
#define OPENSPACE_LAYER 600 //Openspace layer over all
#define OPENSPACE_PLANE -10 //Openspace plane below all turfs //SKYRAT EDIT CHANGE - MOVED TO 10 FROM 9 - Pollution port
#define OPENSPACE_BACKDROP_PLANE -9 //Black square just over openspace plane to guaranteed cover all in openspace turf //SKYRAT EDIT CHANGE - MOVED TO 9 FROM 8 - Pollution port
#define FLOOR_PLANE -8 //SKYRAT EDIT CHANGE - Pollution port
#define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE"
#define OVER_TILE_PLANE -7 //SKYRAT EDIT CHANGE - Pollution port
#define WALL_PLANE -6 //SKYRAT EDIT CHANGE - Pollution port
#define GAME_PLANE -5 //SKYRAT EDIT CHANGE - Pollution port
#define FLOOR_PLANE -7
#define GAME_PLANE_RENDER_TARGET "GAME_PLANE"
#define GAME_PLANE -4
#define MOUSE_TRANSPARENT_PLANE -4 //SKYRAT EDIT ADDITION - Pollution port
#define MOUSE_TRANSPARENT_PLANE_RENDER_TARGET "MOUSE_TRANSPARENT_PLANE" //SKYRAT EDIT ADDITION - Pollution port
#define UNDER_FRILL_PLANE -3
#define UNDER_FRILL_RENDER_TARGET "UNDER_FRILL_PLANE"
#define FRILL_PLANE -2
#define FRILL_PLANE_RENDER_TARGET "FRILL_PLANE"
#define OVER_FRILL_PLANE -1
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE"
#define SPACE_LAYER 1.8
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
@@ -99,10 +93,8 @@
#define GASFIRE_LAYER 5.05
#define RIPPLE_LAYER 5.1
#define LANDMARK_PLANE 50
#define LOW_LANDMARK_LAYER 1
#define MID_LANDMARK_LAYER 2
#define HIGH_LANDMARK_LAYER 3
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define AREA_PLANE 60
#define MASSIVE_OBJ_PLANE 70
@@ -111,13 +103,9 @@
#define RAD_TEXT_PLANE 90
#define FRILL_MASK_PLANE 95
#define FRILL_MASK_RENDER_TARGET "*FRILL_MASK_PLANE"
//---------- LIGHTING -------------
///Normal 1 per turf dynamic lighting underlays
#define LIGHTING_PLANE 100
#define LIGHTING_RENDER_TARGET "LIGHT_PLANE"
///Lighting objects that are "free floating"
#define O_LIGHTING_VISUAL_PLANE 110
@@ -125,7 +113,6 @@
///Things that should render ignoring lighting
#define ABOVE_LIGHTING_PLANE 120
#define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE"
#define LIGHTING_PRIMARY_LAYER 15 //The layer for the main lights of the station
#define LIGHTING_PRIMARY_DIMMER_LAYER 15.1 //The layer that dims the main lights of the station
@@ -134,7 +121,6 @@
///visibility + hiding of things outside of light source range
#define BYOND_LIGHTING_PLANE 130
#define BYOND_LIGHTING_RENDER_TARGET "BYOND_LIGHTING_PLANE"
//---------- EMISSIVES -------------
@@ -152,7 +138,6 @@
///AI Camera Static
#define CAMERA_STATIC_PLANE 200
#define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE"
///Popup Chat Messages
#define RUNECHAT_PLANE 250
@@ -165,7 +150,6 @@
///--------------- FULLSCREEN IMAGES ------------
#define FULLSCREEN_PLANE 500
#define FULLSCREEN_RENDER_TARGET "FULLSCREEN_PLANE"
#define FLASH_LAYER 1
#define FULLSCREEN_LAYER 2
#define UI_DAMAGE_LAYER 3
@@ -174,12 +158,15 @@
#define CURSE_LAYER 6
//-------------------- Rendering ---------------------
#define RENDER_PLANE_GAME 990
#define RENDER_PLANE_NON_GAME 995
#define RENDER_PLANE_MASTER 999
//-------------------- HUD ---------------------
//HUD layer defines
#define HUD_PLANE 1000
#define HUD_RENDER_TARGET "HUD_PLANE"
#define ABOVE_HUD_PLANE 1100
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
#define RADIAL_BACKGROUND_LAYER 0
///1000 is an unimportant number, it's just to normalize copied layers
@@ -187,9 +174,9 @@
#define ADMIN_POPUP_LAYER 1
///Plane of the "splash" icon used that shows on the lobby screen. Nothing should ever be above this.
#define SPLASHSCREEN_PLANE 9999
#define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE"
#define LOBBY_BACKGROUND_LAYER 3
#define LOBBY_BUTTON_LAYER 4

View File

@@ -0,0 +1,52 @@
# The Render Readme
1. [Byond internal functionality](#byond-internal-functionality)
2. [Known internal snowflake](#known-internal-snowflake)
3. [The rendering solution](#the-rendering-solution)
4. [Render plates](#render-plates)
## 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.
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.
## Known internal snowflake
The following is an incomplete list of pitfalls that come from byond snowflake that are known, this list is obviously incomplete.
1. Transforms are very slow on clientside. This is not usually noticable, but if you start using large amounts of them it will grind you to a halt quickly, regardless of whether its on overlays or objs
2. The darkness plane. The darkness plane has specific variables it needs to render correctly, and these can be found in the plane masters file. it is composed internally of two parts, a black mask over the clients screen, and a non rendering mask that blocks all luminosity=0 turfs and their contents from rendering if the SEE_BLACKNESS flag is set properly. It behaves very oddly, such as forcing itself to ALWAYS render or pre-render on blend_multiply blend mode or refusing to render the black mask properly otherwise. The blocker will always block rendering but the mask can be layered under other objects.
3. render_target/source. Render_target/source will only copy certain rendering instructions, and these are only defined as "etc." in the byond reference. Known non copied appearance vars include: blend_mode, plane, layer, vis_contents, mouse_opacity...
4. Large icons on the screen that peek over the edge will instead of only rendering partly like you would expect will instead stretch the screen while not adgusting the render buffer, which means that you can actively see as tiles and map objects are rendered. You can use this for an easy "offscreen" UI.
5. Numerically large filters on objects of any size will torpedo performance, even though large objects with small filters will perform massively better. (ie blur(size=20) BAD)
6. Texture Atlas: the texture atlas byond uses to render icons is very susceptible to corruption and can regularily replace icons with other icons or just not render at all. This can be exasperated by alt tabbing or pausing the dreamseeker process.
7. The renderer is awful code and lummox said he will try changing a large part of it for 515 so keep an eye on that
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
## 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:
![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_old.png)
A semi-fix to stop from having to apply effects to every single plane is to use the render controllers, to automatically apply filters and colors automatically onto their controlled planes.
The solution is thus instead we replace plane masters rendering directly to client with planes that render multiple planes onto them as objects in order to be able to affect multiple planes while treating them as a single object. This is done by relaying the plane using a "render relay" onto a "render plate" which acts as a plane master of plane masters of sorts, and since planes are rendered onto it as single objects any filters we apply to them will render over the planes, treating them as a single unit.
![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_refactored.png)
We can also choose to render these by decreasing the scaling all applied effects (effect_size/number_of_plates_rendered_to) then rendering it onto multiple planes:
![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_refactored_multiple.png)
Through these this allows us to treat planes as single objects, and lets us distort them as a single unit, most notably works wonders with the displacement filter. Specifically, here you can displacement_filter a plane onto a plate, which then will treat all the other planes rendered on that plate as a single unit.
## Render plates
The rendering system uses two objects to unify planes: render_relay and render_plates. Render relays use render_target/source and the relay_render_to_plane proc to replicate the plane master on the render relay. This render relay is then rendered onto a render_plate, which is a plane master that renders the render_relays onto itself. This plate can then be hierachically rendered with the same process until it reaches the master render_plate, which is the plate that will actually render to the player. These plates naturally in the byond style have quirks. For example, rendering to two plates will double any effects such as color or filters, and as such you need to carefully manage how you render them. Keep in mind as well that when sorting the layers for rendering on a plane that they should not be negative, this is handled automatically in relay_render_to_plane. When debugging note that mouse_opacity can act bizzarly with this method, such as only allowing you to click things that are layered over objects on a certain plane but auomatically setting the mouse_opacity should be handling this. Note that if you decide to manipulate a plane with internal byond objects that you will have to manually extrapolate the vars that are set if you want to render them to another plane (See blackness plane for example), and that this is not documented anywhere.
Goodluck and godspeed with coding
- Just another contributor

View File

@@ -6,6 +6,14 @@
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_MASTER
///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
/atom/movable/screen/plane_master/proc/Show(override)
alpha = override || show_alpha
@@ -15,21 +23,30 @@
//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)
///Things rendered on "openspace"; holes in multi-z
/atom/movable/screen/plane_master/openspace
name = "open space plane master"
name = "open space backdrop plane master"
plane = OPENSPACE_BACKDROP_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_MULTIPLY
alpha = 255
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/openspace/Initialize(mapload)
. = ..()
add_filter("multiz_lighting_mask", 1, alpha_mask_filter(render_source = LIGHTING_RENDER_TARGET, flags = MASK_INVERSE))
add_filter("first_stage_openspace", 2, drop_shadow_filter(color = "#04080FAA", size = -10))
add_filter("second_stage_openspace", 3, drop_shadow_filter(color = "#04080FAA", size = -15))
add_filter("third_stage_openspace", 4, drop_shadow_filter(color = "#04080FAA", size = -20))
add_filter("first_stage_openspace", 1, drop_shadow_filter(color = "#04080FAA", size = -10))
add_filter("second_stage_openspace", 2, drop_shadow_filter(color = "#04080FAA", size = -15))
add_filter("third_stage_openspace", 3, drop_shadow_filter(color = "#04080FAA", size = -20))
/atom/movable/screen/plane_master/openspace
name = "open space plane master"
plane = OPENSPACE_PLANE
appearance_flags = PLANE_MASTER
render_relay_plane = RENDER_PLANE_GAME
///Contains just the floor
/atom/movable/screen/plane_master/floor
@@ -37,18 +54,7 @@
plane = FLOOR_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/over_tile
name = "over tile world plane master"
plane = OVER_TILE_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/wall
name = "wall plane master"
plane = WALL_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
///Contains most things in the game world
/atom/movable/screen/plane_master/game_world
@@ -56,64 +62,60 @@
plane = GAME_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/game_world/backdrop(mob/mymob)
remove_filter("AO")
. = ..()
if(istype(mymob) && mymob.client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion))
add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA"))
/atom/movable/screen/plane_master/wall
name = "wall plane master"
plane = WALL_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/under_frill
name = "under frill plane master"
plane = UNDER_FRILL_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/frill
name = "frill plane master"
plane = FRILL_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/area
name = "area plane master"
plane = AREA_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
/atom/movable/screen/plane_master/massive_obj
name = "massive object plane master"
plane = MASSIVE_OBJ_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/ghost
name = "ghost plane master"
plane = GHOST_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_NON_GAME
/atom/movable/screen/plane_master/point
name = "point plane master"
plane = POINT_PLANE
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
/**
* 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
color = list(null, null, null, "#0000", "#000f")
blend_mode = BLEND_MULTIPLY
appearance_flags = PLANE_MASTER | NO_CLIENT_COLOR | PIXEL_SCALE
//byond internal end
render_relay_plane = RENDER_PLANE_GAME
///Contains all lighting objects
/atom/movable/screen/plane_master/lighting
name = "lighting plane master"
plane = LIGHTING_PLANE
blend_mode = BLEND_MULTIPLY
blend_mode_override = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/lighting/backdrop(mob/mymob)
. = ..()
mymob.overlay_fullscreen("lighting_backdrop_lit", /atom/movable/screen/fullscreen/lighting_backdrop/lit)
mymob.overlay_fullscreen("lighting_backdrop_unlit", /atom/movable/screen/fullscreen/lighting_backdrop/unlit)
@@ -127,7 +129,6 @@
* 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.
*/
/atom/movable/screen/plane_master/lighting/Initialize(mapload)
. = ..()
add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE))
@@ -142,33 +143,45 @@
plane = EMISSIVE_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_target = EMISSIVE_RENDER_TARGET
render_relay_plane = null
/atom/movable/screen/plane_master/emissive/Initialize(mapload)
. = ..()
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
appearance_flags = PLANE_MASTER //should use client color
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
///Contains space parallax
/atom/movable/screen/plane_master/parallax
name = "parallax plane master"
plane = PLANE_SPACE_PARALLAX
blend_mode = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/parallax_white
name = "parallax whitifier plane master"
plane = PLANE_SPACE
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/camera_static
name = "camera static plane master"
plane = CAMERA_STATIC_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/excited_turfs
name = "atmos excited turfs"
plane = ATMOS_GROUP_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_GAME
alpha = 0
/atom/movable/screen/plane_master/o_light_visual
@@ -177,14 +190,43 @@
render_target = O_LIGHTING_VISUAL_RENDER_TARGET
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
blend_mode = BLEND_MULTIPLY
render_relay_plane = null
/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")
. = ..()
if(istype(mymob) && mymob.client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion))
add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA"))
/atom/movable/screen/plane_master/gravpulse
name = "gravpulse plane"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
plane = GRAVITY_PULSE_PLANE
render_target = GRAVITY_PULSE_RENDER_TARGET
render_relay_plane = null
/atom/movable/screen/plane_master/area
name = "area plane"
plane = AREA_PLANE
render_relay_plane = RENDER_PLANE_GAME
/atom/movable/screen/plane_master/radtext
name = "radtext plane"
plane = RAD_TEXT_PLANE
render_relay_plane = RENDER_PLANE_NON_GAME
/atom/movable/screen/plane_master/balloon_chat
name = "balloon alert plane"
plane = BALLOON_CHAT_PLANE
render_relay_plane = RENDER_PLANE_NON_GAME
/atom/movable/screen/plane_master/fullscreen
name = "fullscreen alert plane"
plane = FULLSCREEN_PLANE
render_relay_plane = RENDER_PLANE_NON_GAME

View File

@@ -84,12 +84,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/plane_master_controller)
name = PLANE_MASTERS_GAME
controlled_planes = list(
FLOOR_PLANE,
OVER_TILE_PLANE,
WALL_PLANE,
GAME_PLANE,
UNDER_FRILL_PLANE,
FRILL_PLANE,
AREA_PLANE,
MASSIVE_OBJ_PLANE,
GHOST_PLANE,
POINT_PLANE,

View File

@@ -0,0 +1,82 @@
/*!
* 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
*/
/atom/movable/render_plane_relay
screen_loc = "CENTER"
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
/atom/movable/screen/plane_master/rendering_plate/game_world/Initialize(mapload)
. = ..()
add_filter("displacer", 1, displacement_map_filter(render_source = GRAVITY_PULSE_RENDER_TARGET, size = 10))
///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(!render_target && generate_render_target)
render_target = "*[name]: AUTOGENERATED RENDER TGT"
var/atom/movable/render_plane_relay/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.screen += relay
if(plane != BLACKNESS_PLANE) //intenral snowflake do not touch
blend_mode = BLEND_DEFAULT

View File

@@ -59,7 +59,7 @@
/// Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
var/overlay_layer = AREA_LAYER
/// Plane for the overlay
var/overlay_plane = BLACKNESS_PLANE
var/overlay_plane = ABOVE_LIGHTING_PLANE
/// If the weather has no purpose other than looks
var/aesthetic = FALSE
/// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather.

View File

@@ -9,7 +9,7 @@
icon_state = "unknown"
layer = AREA_LAYER
//Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE.
plane = BLACKNESS_PLANE
plane = AREA_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
invisibility = INVISIBILITY_LIGHTING

View File

@@ -40,8 +40,10 @@
cam_screen.del_on_map_removal = FALSE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
var/atom/movable/screen/plane_master/instance = new plane()
if(instance.blend_mode_override)
instance.blend_mode = instance.blend_mode_override
instance.assigned_map = map_name
instance.del_on_map_removal = FALSE
instance.screen_loc = "[map_name]:CENTER"

View File

@@ -95,12 +95,22 @@
///////////////////////
/atom/movable/warp_effect
plane = GRAVITY_PULSE_PLANE
appearance_flags = PIXEL_SCALE // no tile bound so you can see it around corners and so
icon = 'icons/effects/light_overlays/light_352.dmi'
icon_state = "light"
pixel_x = -176
pixel_y = -176
/obj/effect/anomaly/grav
name = "gravitational anomaly"
icon_state = "shield2"
density = FALSE
var/boing = 0
aSignal = /obj/item/assembly/signaler/anomaly/grav
var/boing = 0
///Warp effect holder for displacement filter to "pulse" the anomaly
var/atom/movable/warp_effect/warp
/obj/effect/anomaly/grav/Initialize(mapload, new_lifespan, drops_core)
. = ..()
@@ -109,7 +119,15 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
/obj/effect/anomaly/grav/anomalyEffect()
warp = new(src)
vis_contents += warp
/obj/effect/anomaly/grav/Destroy()
vis_contents -= warp
warp = null
return ..()
/obj/effect/anomaly/grav/anomalyEffect(delta_time)
..()
boing = 1
for(var/obj/O in orange(4, src))
@@ -130,6 +148,10 @@
if(target && !target.stat)
O.throw_at(target, 5, 10)
//anomaly quickly contracts then slowly expands it's ring
animate(warp, time = delta_time*3, transform = matrix().Scale(0.5,0.5))
animate(time = delta_time*7, transform = matrix())
/obj/effect/anomaly/grav/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
gravShock(AM)

View File

@@ -3,7 +3,7 @@
icon = 'icons/effects/landmarks_static.dmi'
icon_state = "x2"
anchored = TRUE
layer = MID_LANDMARK_LAYER
layer = TURF_LAYER
invisibility = INVISIBILITY_ABSTRACT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
@@ -416,7 +416,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
/obj/effect/landmark/event_spawn
name = "generic event spawn"
icon_state = "generic_event"
layer = HIGH_LANDMARK_LAYER
layer = OBJ_LAYER
/obj/effect/landmark/event_spawn/Initialize(mapload)

View File

@@ -68,8 +68,10 @@
// NOT apply to map popups. If there's ever a way to make planesmasters
// omnipresent, then this wouldn't be needed.
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
var/atom/movable/screen/plane_master/instance = new plane()
if(instance.blend_mode_override)
instance.blend_mode = instance.blend_mode_override
instance.assigned_map = "spypopup_map"
instance.del_on_map_removal = FALSE
instance.screen_loc = "spypopup_map:CENTER"

View File

@@ -91,7 +91,7 @@
else
talpha = 255
obj_flags |= BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
plane = BYOND_LIGHTING_PLANE //What matters it's one above openspace, so our animation is not dependant on what's there. Up to revision with 513
plane = ABOVE_LIGHTING_PLANE //What matters it's one above openspace, so our animation is not dependant on what's there. Up to revision with 513
animate(src,alpha = talpha,time = 10)
addtimer(CALLBACK(src,.proc/reset_plane),10)
if(hidden)

View File

@@ -92,10 +92,12 @@
cam_screen.del_on_map_removal = TRUE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
var/atom/movable/screen/plane_master/instance = new plane()
if (!renderLighting && instance.plane == LIGHTING_PLANE)
instance.alpha = 100
if(instance.blend_mode_override)
instance.blend_mode = instance.blend_mode_override
instance.assigned_map = map_name
instance.del_on_map_removal = TRUE
instance.screen_loc = "[map_name]:CENTER"

View File

@@ -434,8 +434,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/character_preview_view)
if (!client)
return
for (var/plane_master_type in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/plane_master/plane_master = new plane_master_type
for (var/plane_master_type in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
var/atom/movable/screen/plane_master/plane_master = new plane_master_type()
plane_master.screen_loc = "[assigned_map]:CENTER"
client?.screen |= plane_master

View File

@@ -43,9 +43,11 @@
cam_screen.del_on_map_removal = FALSE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
var/atom/movable/screen/plane_master/instance = new plane()
instance.assigned_map = map_name
if(instance.blend_mode_override)
instance.blend_mode = instance.blend_mode_override
instance.del_on_map_removal = FALSE
instance.screen_loc = "[map_name]:CENTER"
cam_plane_masters += instance

View File

@@ -81,6 +81,7 @@
notify_volume = 75
)
/obj/singularity/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()

View File

@@ -336,8 +336,6 @@
#include "code\_onclick\hud\pai.dm"
#include "code\_onclick\hud\parallax.dm"
#include "code\_onclick\hud\picture_in_picture.dm"
#include "code\_onclick\hud\plane_master.dm"
#include "code\_onclick\hud\plane_master_controller.dm"
#include "code\_onclick\hud\radial.dm"
#include "code\_onclick\hud\radial_persistent.dm"
#include "code\_onclick\hud\revenanthud.dm"
@@ -345,6 +343,9 @@
#include "code\_onclick\hud\screen_objects.dm"
#include "code\_onclick\hud\screentip.dm"
#include "code\_onclick\hud\swarmer.dm"
#include "code\_onclick\hud\rendering\plane_master.dm"
#include "code\_onclick\hud\rendering\plane_master_controller.dm"
#include "code\_onclick\hud\rendering\render_plate.dm"
#include "code\controllers\admin.dm"
#include "code\controllers\controller.dm"
#include "code\controllers\failsafe.dm"