516 Renderer update (#20579)

Updated the renderers to work with BYOND 516.
Some update of ZAS to hopefully be more efficient, and cold/hot air
effects.
Gas effects are now less prominent.

Ported from Bay
This commit is contained in:
Fluffy
2025-03-22 11:20:21 +00:00
committed by GitHub
parent 2e59f1903e
commit 08b82baea4
18 changed files with 514 additions and 112 deletions
+191 -61
View File
@@ -7,13 +7,23 @@
* 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 = "CENTER"
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
@@ -23,21 +33,20 @@ ABSTRACT_TYPE(/atom/movable/renderer)
/// 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]"
/// If text, uses the text or, if TRUE, uses "*AUTO-[name]".
var/render_target_name = TRUE
var/mob/owner = null
/// When not shared, the mob associated with this renderer.
var/mob/owner
/atom/movable/renderer/Destroy()
owner = null
QDEL_NULL(relay)
owner = null
return ..()
INITIALIZE_IMMEDIATE(/atom/movable/renderer)
/atom/movable/renderer/Initialize(mapload, mob/owner)
. = ..()
if (. == INITIALIZE_HINT_QDEL)
@@ -51,8 +60,10 @@ INITIALIZE_IMMEDIATE(/atom/movable/renderer)
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 = "CENTER"
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
@@ -64,10 +75,11 @@ INITIALIZE_IMMEDIATE(/atom/movable/renderer)
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.
* 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
@@ -81,52 +93,104 @@ INITIALIZE_IMMEDIATE(/atom/movable/renderer)
* to share them globally.
*/
/// The list of renderers associated with this mob.
/mob/var/list/atom/movable/renderer/renderers
/// 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/CreateRenderers()
if (!renderers)
renderers = list()
for (var/renderer as anything in subtypesof(/atom/movable/renderer))
if(ispath(renderer, /atom/movable/renderer/shared))
continue
var/atom/movable/renderer/render = new renderer (null, src)
renderers["[render.plane]"] = render // (render = plane) format for visual debugging
if (render.relay)
my_client.screen += render.relay
my_client.screen += render
/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
for (var/atom/movable/renderer/zrenderer as anything in GLOB.zmimic_renderers)
if (zrenderer.relay)
my_client.screen += zrenderer.relay
my_client.screen += zrenderer
/// Removes the mob's renderers on /Logout()
/mob/proc/RemoveRenderers()
if(my_client)
for(var/renderer as anything in renderers)
var/atom/movable/renderer/render = renderers[renderer]
my_client.screen -= render
if (render.relay)
my_client.screen -= render.relay
qdel(render)
for (var/atom/movable/renderer/renderer as anything in GLOB.zmimic_renderers)
/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
if (renderers)
renderers.Cut()
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 out of
* order, it should have a more appropriate layer value.
* 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"
@@ -134,58 +198,50 @@ INITIALIZE_IMMEDIATE(/atom/movable/renderer)
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
//Z Mimic planemasters -> Could apply scaling for parallax though that requires copying appearances from adjacent turfs
GLOBAL_LIST_EMPTY(zmimic_renderers)
/hook/startup/proc/create_global_renderers() //Some (most) renderers probably do not need to be instantiated per mob. So may as well make them global and just add to screen
//Zmimic planemasters
for(var/i = 0 to OPENTURF_MAX_DEPTH)
GLOB.zmimic_renderers += new /atom/movable/renderer/shared/zmimic(null, null, OPENTURF_MAX_PLANE - i)
return TRUE
/atom/movable/renderer/shared/zmimic
/atom/movable/renderer/zmimic
name = "Zrenderer"
group = RENDER_GROUP_SCENE
/atom/movable/renderer/shared/zmimic/Initialize(mapload, _owner, _plane)
/atom/movable/renderer/zmimic/Initialize(mapload, _owner, _plane)
plane = _plane
name = "Zrenderer [plane]"
. = ..()
/atom/movable/renderer/shared/zmimic/Destroy()
GLOB.zmimic_renderers -= src
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
/atom/movable/renderer/roofs
name = "Roofs"
group = RENDER_GROUP_SCENE
plane = ROOF_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/// Draws darkness effects.
/atom/movable/renderer/lighting
@@ -194,6 +250,8 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
plane = LIGHTING_PLANE
relay_blend_mode = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
renderer_flags = RENDERER_FLAG_AUTO
/atom/movable/renderer/lighting/Initialize()
. = ..()
@@ -203,11 +261,13 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
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.
@@ -216,6 +276,7 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
group = RENDER_GROUP_SCENE
plane = FULLSCREEN_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
renderer_flags = RENDERER_FLAG_AUTO
/// Draws user interface elements.
@@ -223,6 +284,7 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
name = "Interface"
group = RENDER_GROUP_SCREEN
plane = HUD_PLANE
renderer_flags = RENDERER_FLAG_AUTO
/* *
@@ -235,17 +297,21 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
* 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.
@@ -253,6 +319,7 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
name = "Final Group"
group = RENDER_GROUP_NONE
plane = RENDER_GROUP_FINAL
renderer_flags = RENDERER_FLAG_AUTO
/* *
@@ -264,6 +331,7 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
* 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"
@@ -271,14 +339,57 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
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 = "*warp",
size = 5
)
filters += filter(
type = "displace",
render_source = HEAT_COMPOSITE_TARGET,
size = 2.5
)
/*!
* This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers.
* 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.
@@ -290,12 +401,16 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
* 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()
. = ..()
@@ -303,3 +418,18 @@ GLOBAL_LIST_EMPTY(zmimic_renderers)
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