8dbf1cf4ec
Further changes to comply with the ToS More ToS cleanup Bye bye George Melons Better to be safe than sorry
144 lines
4.8 KiB
Plaintext
144 lines
4.8 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(turf/new_turf, 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(delta_r, delta_g, 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
|
|
SSlighting.corners_queue += 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
|
|
SSlighting.objects_queue += 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 brain damaged and needs his head checked. Thanks. Send them my regards by the way.")
|
|
|
|
return ..()
|