mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
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:
@@ -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
|
||||
|
||||
52
code/_onclick/hud/rendering/_render_readme.md
Normal file
52
code/_onclick/hud/rendering/_render_readme.md
Normal 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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
82
code/_onclick/hud/rendering/render_plate.dm
Normal file
82
code/_onclick/hud/rendering/render_plate.dm
Normal 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
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
notify_volume = 75
|
||||
)
|
||||
|
||||
|
||||
/obj/singularity/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user