mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
This *seems* to be a decent speed up just in the appearent time it takes break all lights to process, and dview wasn't really needed here. Minor oddies can occur on bigger lights near their edges, but not enough to justify the extra cost.
139 lines
4.7 KiB
Plaintext
139 lines
4.7 KiB
Plaintext
// Because we can control each corner of every lighting object.
|
|
// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't).
|
|
// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting.
|
|
|
|
// This list is what the code that assigns corners listens to, the order in this list is the order in which corners are added to the /turf/corners list.
|
|
GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST))
|
|
|
|
/datum/lighting_corner
|
|
var/list/turf/masters
|
|
var/list/datum/light_source/affecting // Light sources affecting us.
|
|
var/active = FALSE // TRUE if one of our masters has dynamic lighting.
|
|
|
|
var/x = 0
|
|
var/y = 0
|
|
var/z = 0
|
|
|
|
var/lum_r = 0
|
|
var/lum_g = 0
|
|
var/lum_b = 0
|
|
|
|
var/needs_update = FALSE
|
|
|
|
var/cache_r = LIGHTING_SOFT_THRESHOLD
|
|
var/cache_g = LIGHTING_SOFT_THRESHOLD
|
|
var/cache_b = LIGHTING_SOFT_THRESHOLD
|
|
var/cache_mx = 0
|
|
|
|
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
|
|
. = ..()
|
|
masters = list()
|
|
masters[new_turf] = turn(diagonal, 180)
|
|
z = new_turf.z
|
|
|
|
var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction.
|
|
var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one.
|
|
|
|
x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5)
|
|
y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5)
|
|
|
|
// My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal).
|
|
// Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered.
|
|
// So we'll have this hardcode instead.
|
|
var/turf/T
|
|
var/i
|
|
|
|
// Diagonal one is easy.
|
|
T = get_step(new_turf, diagonal)
|
|
if (T) // In case we're on the map's border.
|
|
if (!T.corners)
|
|
T.corners = list(null, null, null, null)
|
|
|
|
masters[T] = diagonal
|
|
i = GLOB.LIGHTING_CORNER_DIAGONAL.Find(turn(diagonal, 180))
|
|
T.corners[i] = src
|
|
|
|
// Now the horizontal one.
|
|
T = get_step(new_turf, horizontal)
|
|
if (T) // Ditto.
|
|
if (!T.corners)
|
|
T.corners = list(null, null, null, null)
|
|
|
|
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
|
|
i = GLOB.LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
|
|
T.corners[i] = src
|
|
|
|
// And finally the vertical one.
|
|
T = get_step(new_turf, vertical)
|
|
if (T)
|
|
if (!T.corners)
|
|
T.corners = list(null, null, null, null)
|
|
|
|
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
|
|
i = GLOB.LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
|
|
T.corners[i] = src
|
|
|
|
update_active()
|
|
|
|
/datum/lighting_corner/proc/update_active()
|
|
active = FALSE
|
|
var/turf/T
|
|
var/thing
|
|
for (thing in masters)
|
|
T = thing
|
|
if (T.lighting_object)
|
|
active = TRUE
|
|
|
|
// God that was a mess, now to do the rest of the corner code! Hooray!
|
|
/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b)
|
|
lum_r += delta_r
|
|
lum_g += delta_g
|
|
lum_b += delta_b
|
|
|
|
if (!needs_update)
|
|
needs_update = TRUE
|
|
GLOB.lighting_update_corners += src
|
|
|
|
/datum/lighting_corner/proc/update_objects()
|
|
// Cache these values a head of time so 4 individual lighting objects don't all calculate them individually.
|
|
var/lum_r = src.lum_r
|
|
var/lum_g = src.lum_g
|
|
var/lum_b = src.lum_b
|
|
var/mx = max(lum_r, lum_g, lum_b) // Scale it so one of them is the strongest lum, if it is above 1.
|
|
. = 1 // factor
|
|
if (mx > 1)
|
|
. = 1 / mx
|
|
|
|
#if LIGHTING_SOFT_THRESHOLD != 0
|
|
else if (mx < LIGHTING_SOFT_THRESHOLD)
|
|
. = 0 // 0 means soft lighting.
|
|
|
|
cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
|
|
cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
|
|
cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
|
|
#else
|
|
cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE)
|
|
cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE)
|
|
cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE)
|
|
#endif
|
|
cache_mx = round(mx, LIGHTING_ROUND_VALUE)
|
|
|
|
for (var/TT in masters)
|
|
var/turf/T = TT
|
|
if (T.lighting_object)
|
|
if (!T.lighting_object.needs_update)
|
|
T.lighting_object.needs_update = TRUE
|
|
GLOB.lighting_update_objects += T.lighting_object
|
|
|
|
|
|
/datum/lighting_corner/dummy/New()
|
|
return
|
|
|
|
|
|
/datum/lighting_corner/Destroy(var/force)
|
|
if (!force)
|
|
return QDEL_HINT_LETMELIVE
|
|
|
|
stack_trace("Ok, Look, TG, I need you to find whatever fucker decided to call qdel on a fucking lighting corner, then tell him very nicely and politely that he is 100% retarded and needs his head checked. Thanks. Send them my regards by the way.")
|
|
|
|
return ..() |