Files
Bubberstation/code/modules/lighting/lighting_turf.dm
T
LemonInTheDark f88edef0fb Space/Changeturf fixes and optimizations (#73261)
## About The Pull Request

We've got a few space related things that are busted, and shuttle
movement is slow.
I'd like to try to improve these things, if just a bit.

Long list of only tenuously related topics. Sorry for the shotgun blast

#### [Fixes lazyloaded stuff having bad
space](https://github.com/tgstation/tgstation/commit/d4de176a63f87d0f820e0cb610cd192750c897d6)

We need to handle area transferring in maploading code under niche
cases, and we also need to actually init reservation spaces we create.

It's also redundant and potentially dupe creating to do area lighting
handling in changeturf, because it gets touched in turf init anyway. Old
me is stupid.

#### [Adds some doc comments, yeets
ssmappping/transit](https://github.com/tgstation/tgstation/commit/269717145d70a4a73198791ca50253c708ee3ac1)

We had a reserved space for just shuttles to use, except it wasn't for
just shuttles.
So in theory if the space got clogged with other shit, the shuttles
could have nowhere to actually use.

It's better to just have the two groups share real estate. More sane

### The "Starlight is Slow" Block

#### [Starlight optimization part one (don't check config for each
individual turf you check for
activity)](https://github.com/tgstation/tgstation/commit/7312a314bef281c1b85a377cf2dcb647a2045050)

#### [Starlight optimization part two (infer
context)](https://github.com/tgstation/tgstation/commit/be94c422ed76aa3f07b43cad4d1dc6b6148f135f)

Starlight was causing each space turf to cause itself and its neighbor
to constantly recheck if they had starlight off changeturf.

The exact same effect can be had by taking advantage of some
pre-existing information, namely if the space turf is gaining or losing
a source of starlight.
Essentially, instead of telling a turf to check all adjacent turfs to
see if it's got starlight, we tell the turf if WE are a source of
starlight, or if we might be taking something away from it.

There's a bit of wasted cpu here but not much, if it's worth doing a
register signal pattern for clearing depends on the case we're working
with.

Being intelligent about this makes things much faster, something in the
neighborhood of 4 to 3 fold.
I've also made openspace's starlight work better, cause the old pattern
was a bit silly.

### Changeturf is Annoying (Microops)

#### [Micro ops changeturf and turf deletion a
bit](https://github.com/tgstation/tgstation/commit/386b3ab7fc2a820a9ffe3d2e39d78f96dc562d64)

Don't do work if the thing you're working on doesn't exist, don't check
every adjacent turf for firelocks on turf change (just have thefirelocks
manage that), don't check all atoms on the turf for decals on turf
change, similar.
Also moves visibility changes from camera code into changeturf, to avoid
unneeded work.

Needs some extra work to optimize the guts for this path but I can do
that!

#### [Micros camera vis
changes](https://github.com/tgstation/tgstation/commit/ebab69e9ea4adffd8787671f309f4ba27756c82e)

We should only update vis when our opacity changes. 
In addition, we don't need all the camera handling fluff if we only want
to update our turf's static groups.

Also micros a camera net helper to be less crap for non multiz maps

#### [Micros some open space atmos cases, alongside avoiding a for(null)
in opacity
handling](https://github.com/tgstation/tgstation/commit/72ae07ba1db1fb1c4434a4cdaecc78ea6a2864fc)

#### [Ensures space_lit tiles never accidentially inherit lighting
objects](https://github.com/tgstation/tgstation/commit/a99ff2265a4d1b157849fb7485adee17a3250df5)

S dumb, and leads to space turfs having two sources of lighting, which
looks wrong.
This was invisible when their lighting was fullbright, but it sucks now.


### Misc Stuff

#### [Cleans up stat tracking a bit to avoid
collisions](https://github.com/tgstation/tgstation/commit/40fb8f21e20d5bd9ef2f989eb166e03b30d66b3d)

#### [Cleans up a turf helper to not be
stupid](https://github.com/tgstation/tgstation/commit/bf4ee6710026e6ca9922d0f1fa49020ebde8cd6f)

WHY ARE YOU USING THE RANGED TURF HELPER IF YOU GO ONE TILE

#### [Moves transit turf signal cleanup to destroy, I named this proc
wrong](https://github.com/tgstation/tgstation/commit/c85c2cfc86f3b2dd224cae6b12e2fc428846c30b)

I'm sorry @Time-Green 

#### [Adds better transit caching to
shuttles](https://github.com/tgstation/tgstation/commit/35e85334c4f815da0cadd8172e9908267a01d334)

Adds a max reserved transit size to the shuttle subsystem, to keep
things in bounds.
In addition, adds a soft cap under which existing transit space will get
hold onto, to make repeated non escape/arrive shuttle movements faster

Hopefully this makes common shuttle moves less bad.
## Why It's Good For The Game

Speed
2023-02-06 23:04:50 -05:00

117 lines
3.9 KiB
Plaintext

// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
/turf/proc/reconsider_lights()
lighting_corner_NE?.vis_update()
lighting_corner_SE?.vis_update()
lighting_corner_SW?.vis_update()
lighting_corner_NW?.vis_update()
/turf/proc/lighting_clear_overlay()
if (lighting_object)
qdel(lighting_object, force=TRUE)
// Builds a lighting object for us, but only if our area is dynamic.
/turf/proc/lighting_build_overlay()
if (lighting_object)
qdel(lighting_object, force=TRUE) //Shitty fix for lighting objects persisting after death
new /datum/lighting_object(src)
// Used to get a scaled lumcount.
/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
if (!lighting_object)
return 1
var/totallums = 0
var/datum/lighting_corner/L
L = lighting_corner_NE
if (L)
totallums += L.lum_r + L.lum_b + L.lum_g
L = lighting_corner_SE
if (L)
totallums += L.lum_r + L.lum_b + L.lum_g
L = lighting_corner_SW
if (L)
totallums += L.lum_r + L.lum_b + L.lum_g
L = lighting_corner_NW
if (L)
totallums += L.lum_r + L.lum_b + L.lum_g
totallums /= 12 // 4 corners, each with 3 channels, get the average.
totallums = (totallums - minlum) / (maxlum - minlum)
totallums += dynamic_lumcount
return CLAMP01(totallums)
// Returns a boolean whether the turf is on soft lighting.
// Soft lighting being the threshold at which point the overlay considers
// itself as too dark to allow sight and see_in_dark becomes useful.
// So basically if this returns true the tile is unlit black.
/turf/proc/is_softly_lit()
if (!lighting_object)
return FALSE
return !(luminosity || dynamic_lumcount)
///Proc to add movable sources of opacity on the turf and let it handle lighting code.
/turf/proc/add_opacity_source(atom/movable/new_source)
LAZYADD(opacity_sources, new_source)
if(opacity)
return
recalculate_directional_opacity()
///Proc to remove movable sources of opacity on the turf and let it handle lighting code.
/turf/proc/remove_opacity_source(atom/movable/old_source)
LAZYREMOVE(opacity_sources, old_source)
if(opacity) //Still opaque, no need to worry on updating.
return
recalculate_directional_opacity()
///Calculate on which directions this turfs block view.
/turf/proc/recalculate_directional_opacity()
. = directional_opacity
if(opacity)
directional_opacity = ALL_CARDINALS
if(. != directional_opacity)
reconsider_lights()
return
directional_opacity = NONE
if(opacity_sources)
for(var/atom/movable/opacity_source as anything in opacity_sources)
if(opacity_source.flags_1 & ON_BORDER_1)
directional_opacity |= opacity_source.dir
else //If fulltile and opaque, then the whole tile blocks view, no need to continue checking.
directional_opacity = ALL_CARDINALS
break
if(. != directional_opacity && (. == ALL_CARDINALS || directional_opacity == ALL_CARDINALS))
reconsider_lights() //The lighting system only cares whether the tile is fully concealed from all directions or not.
///Transfer the lighting of one area to another
/turf/proc/transfer_area_lighting(area/old_area, area/new_area)
if(SSlighting.initialized && !space_lit)
if (new_area.static_lighting != old_area.static_lighting)
if (new_area.static_lighting)
lighting_build_overlay()
else
lighting_clear_overlay()
// We will only run this logic on turfs off the prime z layer
// Since on the prime z layer, we use an overlay on the area instead, to save time
if(SSmapping.z_level_to_plane_offset[z])
var/index = SSmapping.z_level_to_plane_offset[z] + 1
//Inherit overlay of new area
if(old_area.lighting_effects)
cut_overlay(old_area.lighting_effects[index])
if(new_area.lighting_effects)
add_overlay(new_area.lighting_effects[index])
// If we're changing into an area with no lighting, and we're lit, light ourselves
if(!new_area.lighting_effects && old_area.lighting_effects && space_lit)
overlays += GLOB.fullbright_overlays[GET_TURF_PLANE_OFFSET(src) + 1]