mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-13 10:23:15 +00:00
Removed a bunch of back reference lists that were either entirely unused, or contained references that could be found within the datums contained in other lists. lighting corner datums now get deleted with unused. light sources no longer track lighting corners where the appiled light rounds to 0. Fix lighting on turfs that gained dynamic lighting mid round. lazy init corner datums. these two are related. by decoupling corner datums from the turfs dynamic lighting state, we can use them to know what level of light a non-dynamic light turf should have once it gains dynamic light. Also should free up some memory not storing these datums in maint. Corner datums only exist on a turf that has light cast upon it by the dynamic lighting system. Lighting corners are now lazy inited and deleted. they should always (and only exist) if there is a light source shining on it within range (even if the turf has no dynamic lighting). This is needed to support turfs that become lighting enabled mid round. On the plus side, they will no longer be generated on full dark turfs.
263 lines
7.8 KiB
Plaintext
263 lines
7.8 KiB
Plaintext
// This is where the fun begins.
|
|
// These are the main datums that emit light.
|
|
|
|
/datum/light_source
|
|
var/atom/top_atom // The atom we're emitting light from (for example a mob if we're from a flashlight that's being held).
|
|
var/atom/source_atom // The atom that we belong to.
|
|
|
|
var/turf/source_turf // The turf under the above.
|
|
var/turf/pixel_turf // The turf the top_atom appears to over.
|
|
var/light_power // Intensity of the emitter light.
|
|
var/light_range // The range of the emitted light.
|
|
var/light_color // The colour of the light, string, decomposed by parse_light_color()
|
|
|
|
// Variables for keeping track of the colour.
|
|
var/lum_r
|
|
var/lum_g
|
|
var/lum_b
|
|
|
|
// The lumcount values used to apply the light.
|
|
var/tmp/applied_lum_r
|
|
var/tmp/applied_lum_g
|
|
var/tmp/applied_lum_b
|
|
|
|
var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners.
|
|
|
|
var/applied = FALSE // Whether we have applied our light yet or not.
|
|
|
|
var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update.
|
|
|
|
|
|
/datum/light_source/New(atom/owner, atom/top)
|
|
source_atom = owner // Set our new owner.
|
|
LAZYADD(source_atom.light_sources, src)
|
|
top_atom = top
|
|
if (top_atom != source_atom)
|
|
LAZYADD(top_atom.light_sources, src)
|
|
|
|
source_turf = top_atom
|
|
pixel_turf = get_turf_pixel(top_atom) || source_turf
|
|
|
|
light_power = source_atom.light_power
|
|
light_range = source_atom.light_range
|
|
light_color = source_atom.light_color
|
|
|
|
PARSE_LIGHT_COLOR(src)
|
|
|
|
update()
|
|
|
|
/datum/light_source/Destroy(force)
|
|
remove_lum()
|
|
if (source_atom)
|
|
LAZYREMOVE(source_atom.light_sources, src)
|
|
|
|
if (top_atom)
|
|
LAZYREMOVE(top_atom.light_sources, src)
|
|
|
|
if (needs_update)
|
|
SSlighting.sources_queue -= src
|
|
|
|
top_atom = null
|
|
source_atom = null
|
|
source_turf = null
|
|
pixel_turf = null
|
|
. = ..()
|
|
|
|
// Yes this doesn't align correctly on anything other than 4 width tabs.
|
|
// If you want it to go switch everybody to elastic tab stops.
|
|
// Actually that'd be great if you could!
|
|
#define EFFECT_UPDATE(level) \
|
|
if (needs_update == LIGHTING_NO_UPDATE) \
|
|
SSlighting.sources_queue += src; \
|
|
if (needs_update < level) \
|
|
needs_update = level; \
|
|
|
|
|
|
// This proc will cause the light source to update the top atom, and add itself to the update queue.
|
|
/datum/light_source/proc/update(atom/new_top_atom)
|
|
// This top atom is different.
|
|
if (new_top_atom && new_top_atom != top_atom)
|
|
if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom.
|
|
LAZYREMOVE(top_atom.light_sources, src)
|
|
|
|
top_atom = new_top_atom
|
|
|
|
if (top_atom != source_atom)
|
|
LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom.
|
|
|
|
EFFECT_UPDATE(LIGHTING_CHECK_UPDATE)
|
|
|
|
// Will force an update without checking if it's actually needed.
|
|
/datum/light_source/proc/force_update()
|
|
EFFECT_UPDATE(LIGHTING_FORCE_UPDATE)
|
|
|
|
// Will cause the light source to recalculate turfs that were removed or added to visibility only.
|
|
/datum/light_source/proc/vis_update()
|
|
EFFECT_UPDATE(LIGHTING_VIS_UPDATE)
|
|
|
|
// Macro that applies light to a new corner.
|
|
// It is a macro in the interest of speed, yet not having to copy paste it.
|
|
// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line.
|
|
// As such this all gets counted as a single line.
|
|
// The braces and semicolons are there to be able to do this on a single line.
|
|
#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
|
|
|
|
#define APPLY_CORNER(C) \
|
|
. = LUM_FALLOFF(C, pixel_turf); \
|
|
. *= light_power; \
|
|
var/OLD = effect_str[C]; \
|
|
\
|
|
C.update_lumcount \
|
|
( \
|
|
(. * lum_r) - (OLD * applied_lum_r), \
|
|
(. * lum_g) - (OLD * applied_lum_g), \
|
|
(. * lum_b) - (OLD * applied_lum_b) \
|
|
); \
|
|
|
|
#define REMOVE_CORNER(C) \
|
|
. = -effect_str[C]; \
|
|
C.update_lumcount \
|
|
( \
|
|
. * applied_lum_r, \
|
|
. * applied_lum_g, \
|
|
. * applied_lum_b \
|
|
);
|
|
|
|
// This is the define used to calculate falloff.
|
|
|
|
/datum/light_source/proc/remove_lum()
|
|
applied = FALSE
|
|
for (var/datum/lighting_corner/corner as anything in effect_str)
|
|
REMOVE_CORNER(corner)
|
|
LAZYREMOVE(corner.affecting, src)
|
|
|
|
effect_str = null
|
|
|
|
/datum/light_source/proc/recalc_corner(datum/lighting_corner/C)
|
|
LAZYINITLIST(effect_str)
|
|
if (effect_str[C]) // Already have one.
|
|
REMOVE_CORNER(C)
|
|
effect_str[C] = 0
|
|
|
|
APPLY_CORNER(C)
|
|
effect_str[C] = .
|
|
|
|
|
|
/datum/light_source/proc/update_corners()
|
|
var/update = FALSE
|
|
var/atom/source_atom = src.source_atom
|
|
|
|
if (QDELETED(source_atom))
|
|
qdel(src)
|
|
return
|
|
|
|
if (source_atom.light_power != light_power)
|
|
light_power = source_atom.light_power
|
|
update = TRUE
|
|
|
|
if (source_atom.light_range != light_range)
|
|
light_range = source_atom.light_range
|
|
update = TRUE
|
|
|
|
if (!top_atom)
|
|
top_atom = source_atom
|
|
update = TRUE
|
|
|
|
if (!light_range || !light_power)
|
|
qdel(src)
|
|
return
|
|
|
|
if (isturf(top_atom))
|
|
if (source_turf != top_atom)
|
|
source_turf = top_atom
|
|
pixel_turf = source_turf
|
|
update = TRUE
|
|
else if (top_atom.loc != source_turf)
|
|
source_turf = top_atom.loc
|
|
pixel_turf = get_turf_pixel(top_atom)
|
|
update = TRUE
|
|
else
|
|
var/P = get_turf_pixel(top_atom)
|
|
if (P != pixel_turf)
|
|
pixel_turf = P
|
|
update = TRUE
|
|
|
|
if (!isturf(source_turf))
|
|
if (applied)
|
|
remove_lum()
|
|
return
|
|
|
|
if (light_range && light_power && !applied)
|
|
update = TRUE
|
|
|
|
if (source_atom.light_color != light_color)
|
|
light_color = source_atom.light_color
|
|
PARSE_LIGHT_COLOR(src)
|
|
update = TRUE
|
|
|
|
else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b)
|
|
update = TRUE
|
|
|
|
if (update)
|
|
needs_update = LIGHTING_CHECK_UPDATE
|
|
applied = TRUE
|
|
else if (needs_update == LIGHTING_CHECK_UPDATE)
|
|
return //nothing's changed
|
|
|
|
var/list/datum/lighting_corner/corners = list()
|
|
var/list/turf/turfs = list()
|
|
|
|
if (source_turf)
|
|
var/oldlum = source_turf.luminosity
|
|
source_turf.luminosity = CEILING(light_range, 1)
|
|
for(var/turf/T in view(CEILING(light_range, 1), source_turf))
|
|
if(!IS_OPAQUE_TURF(T))
|
|
if (!T.lighting_corners_initialised)
|
|
T.generate_missing_corners()
|
|
corners[T.lighting_corner_NE] = 0
|
|
corners[T.lighting_corner_SE] = 0
|
|
corners[T.lighting_corner_SW] = 0
|
|
corners[T.lighting_corner_NW] = 0
|
|
turfs += T
|
|
source_turf.luminosity = oldlum
|
|
|
|
var/list/datum/lighting_corner/new_corners = (corners - effect_str)
|
|
LAZYINITLIST(effect_str)
|
|
if (needs_update == LIGHTING_VIS_UPDATE)
|
|
for (var/datum/lighting_corner/corner as anything in new_corners)
|
|
APPLY_CORNER(corner)
|
|
if (. != 0)
|
|
LAZYADD(corner.affecting, src)
|
|
effect_str[corner] = .
|
|
else
|
|
for (var/datum/lighting_corner/corner as anything in new_corners)
|
|
APPLY_CORNER(corner)
|
|
if (. != 0)
|
|
LAZYADD(corner.affecting, src)
|
|
effect_str[corner] = .
|
|
|
|
for (var/datum/lighting_corner/corner as anything in corners - new_corners) // Existing corners
|
|
APPLY_CORNER(corner)
|
|
if (. != 0)
|
|
effect_str[corner] = .
|
|
else
|
|
LAZYREMOVE(corner.affecting, src)
|
|
effect_str -= corner
|
|
|
|
var/list/datum/lighting_corner/gone_corners = effect_str - corners
|
|
for (var/datum/lighting_corner/corner as anything in gone_corners)
|
|
REMOVE_CORNER(corner)
|
|
LAZYREMOVE(corner.affecting, src)
|
|
effect_str -= gone_corners
|
|
|
|
applied_lum_r = lum_r
|
|
applied_lum_g = lum_g
|
|
applied_lum_b = lum_b
|
|
|
|
UNSETEMPTY(effect_str)
|
|
|
|
#undef EFFECT_UPDATE
|
|
#undef LUM_FALLOFF
|
|
#undef REMOVE_CORNER
|
|
#undef APPLY_CORNER
|