Files
S.P.L.U.R.T-Station-13/code/modules/lighting/lighting_corner.dm
kevinz000 e9068f05eb let's play the optimization game featuring lighting (#12310)
* debug proc

* kinda quirky

* let's play the lighting game

* let's play the macro game

* let's play the refactor game

* let's play the optimization game

* let's play the optimization game x2

* yeehaw

* e

* let's play the memory game

* fix

* lighting fix

* sanitization and checks

* mh

* hotkeys fix

* ok
2020-05-23 22:47:42 +02:00

127 lines
4.2 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.
/datum/lighting_corner
var/turf/northeast
var/turf/northwest
var/turf/southeast
var/turf/southwest
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
// Diagonal is our direction FROM them, not to.
/datum/lighting_corner/New(turf/new_turf, diagonal)
. = ..()
#define SET_DIAGONAL(turf, diagonal) \
switch(diagonal){ \
if(SOUTHWEST) { northeast = turf; turf.lc_bottomleft = src; } \
if(SOUTHEAST) { northwest = turf; turf.lc_bottomright = src; } \
if(NORTHEAST) { southwest = turf; turf.lc_topright = src; } \
if(NORTHWEST) { southeast = turf; turf.lc_topleft = src; } \
}
SET_DIAGONAL(new_turf, diagonal)
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)
var/turf/T
// Build diagonal one
T = get_step(new_turf, diagonal)
if(T)
SET_DIAGONAL(T, turn(diagonal, 180))
// Build horizontal
T = get_step(new_turf, horizontal)
if(T)
SET_DIAGONAL(T, turn(((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH), 180))
// Build vertical
T = get_step(new_turf, vertical)
if(T)
SET_DIAGONAL(T, turn(((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH), 180))
update_active()
#undef SET_DIAGONAL
/datum/lighting_corner/proc/update_active()
active = FALSE
if(northeast?.lighting_object || northwest?.lighting_object || southeast?.lighting_object || southwest?.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)
if ((abs(delta_r)+abs(delta_g)+abs(delta_b)) == 0)
return
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)
#define QUEUE(turf) if(turf?.lighting_object && !turf.lighting_object.needs_update) { turf.lighting_object.needs_update = TRUE; GLOB.lighting_update_objects += turf.lighting_object }
QUEUE(northeast)
QUEUE(northwest)
QUEUE(southeast)
QUEUE(southwest)
#undef QUEUE
/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% stupid and needs his head checked. Thanks. Send them my regards by the way.")
return ..()