Z-Lights Mk 2 (#4383)

changes:
Bidirectional source Z-lights have been reverted to single-direction in favor of corner z-bleed.
Z-mimic turfs will now average their light level with their mimiced turf to better approximate Z-lighting.
Openspaces have been made significantly less dark.
Corners no longer incorrectly always take the instant update pathway.
MultiZ helpers are now macros.
More things now properly respect area dynamic lighting settings.
This commit is contained in:
Lohikar
2018-04-27 23:10:59 +03:00
committed by Erki
parent ec553e5796
commit 7ef4090f00
17 changed files with 151 additions and 75 deletions
+89 -12
View File
@@ -11,16 +11,20 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
/datum/lighting_corner
var/turf/t1 // These are in no particular order.
var/t1i // Our index in this turf's corners list.
var/turf/t2
var/t2i
var/turf/t3
var/t3i
var/turf/t4
var/t4i
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/x = 0
var/y = 0
var/z = 0
var/lum_r = 0
var/lum_g = 0
@@ -34,11 +38,12 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
var/cache_b = LIGHTING_SOFT_THRESHOLD
var/cache_mx = 0
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
/datum/lighting_corner/New(turf/new_turf, diagonal)
SSlighting.lighting_corners += src
t1 = new_turf
z = new_turf.z
t1i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal]
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.
@@ -60,6 +65,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
t2 = T
i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal]
t2i = i
T.corners[i] = src
// Now the horizontal one.
@@ -70,6 +76,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
t3 = T
i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
t3i = i
T.corners[i] = src
// And finally the vertical one.
@@ -80,6 +87,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
t4 = T
i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
t4i = i
T.corners[i] = src
update_active()
@@ -95,18 +103,21 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
#undef OVERLAY_PRESENT
// 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, var/delta_u, var/now = FALSE)
/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b, delta_u, now = FALSE)
if (!(delta_r + delta_g + delta_b)) // Don't check u since the overlay doesn't care about it.
return
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
lum_u += delta_u
if (needs_update || !(delta_r + delta_g + delta_b)) // Don't check u since the overlay doesn't care about it.
// This needs to be down here instead of the above if so the lum values are properly updated.
if (needs_update)
return
if (!now)
needs_update = TRUE
update_overlays(FALSE)
SSlighting.corner_queue += src
else
update_overlays(TRUE)
@@ -122,9 +133,60 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
} \
}
/datum/lighting_corner/proc/update_overlays(var/now = FALSE)
#define AVERAGE_BELOW_CORNER(Tt, Ti) \
if (TURF_IS_MIMICING(Tt)) { \
T = GET_BELOW(Tt); \
if (T && T.corners && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \
C = T.corners[Ti]; \
if (C) { \
divisor += 1; \
lr += C.lum_r; \
lg += C.lum_g; \
lb += C.lum_b; \
} \
} \
}
#define UPDATE_ABOVE_CORNER(Tt, Ti) \
if (Tt) { \
T = GET_ABOVE(Tt); \
if (TURF_IS_MIMICING(T) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \
if (!T.corners) { \
T.generate_missing_corners(); \
} \
C = T.corners[Ti]; \
if (C && !C.needs_update) { \
C.update_overlays(FALSE); \
} \
} \
}
/datum/lighting_corner/proc/update_overlays(now = FALSE)
var/lr = lum_r
var/lg = lum_g
var/lb = lum_b
#ifdef USE_CORNER_ZBLEED
var/divisor = 1
var/datum/lighting_corner/C
var/turf/T
AVERAGE_BELOW_CORNER(t1, t1i)
AVERAGE_BELOW_CORNER(t2, t2i)
AVERAGE_BELOW_CORNER(t3, t3i)
AVERAGE_BELOW_CORNER(t4, t4i)
if (divisor > 1)
lr /= divisor
lg /= divisor
lb /= divisor
#endif
// Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually.
var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1.
var/mx = max(lr, lg, lb) // Scale it so 1 is the strongest lum, if it is above 1.
. = 1 // factor
if (mx > 1)
. = 1 / mx
@@ -132,9 +194,13 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
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
if (.)
cache_r = round(lr * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_g = round(lg * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_b = round(lb * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
else
cache_r = cache_g = cache_b = LIGHTING_SOFT_THRESHOLD
cache_mx = round(mx, LIGHTING_ROUND_VALUE)
UPDATE_MASTER(t1)
@@ -142,7 +208,18 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1)
UPDATE_MASTER(t3)
UPDATE_MASTER(t4)
#ifdef USE_CORNER_ZBLEED
UPDATE_ABOVE_CORNER(t1, t1i)
UPDATE_ABOVE_CORNER(t2, t2i)
UPDATE_ABOVE_CORNER(t3, t3i)
UPDATE_ABOVE_CORNER(t4, t4i)
#endif
#undef UPDATE_MASTER
#undef AVERAGE_BELOW_CORNER
#undef UPDATE_ABOVE_CORNER
/datum/lighting_corner/Destroy(force = FALSE)
crash_with("Some fuck [force ? "force-" : ""]deleted a lighting corner.")
+6 -20
View File
@@ -355,12 +355,7 @@
var/test_x
var/test_y
var/zlights_going_up = FALSE
var/turf/originalT // This is needed to reset our search point for bidirectional Z-lights.
FOR_DVIEW(originalT, Ceiling(actual_range), source_turf, 0)
T = originalT
zlights_going_up = FALSE
FOR_DVIEW(T, Ceiling(actual_range), source_turf, 0)
check_t:
if (light_angle && !facing_opaque) // Directional lighting coordinate filter.
@@ -371,7 +366,7 @@
if ((PSEUDO_WEDGE(limit_a_x, limit_a_y, test_x, test_y) > 0) || (PSEUDO_WEDGE(test_x, test_y, limit_b_x, limit_b_y) > 0))
continue
if (T.dynamic_lighting || T.light_sources)
if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources)
Tcorners = T.corners
if (!T.lighting_corners_initialised)
T.lighting_corners_initialised = TRUE
@@ -396,19 +391,10 @@
// Note: above is defined on ALL turfs, but below is only defined on OPEN TURFS.
zlight_check:
if (zlights_going_up) // If we're searching upwards, check above.
if (istype(T.above)) // We escape the goto loop if this condition is false.
T = T.above
goto check_t
else
if (T && (T.flags & MIMIC_BELOW) && T.below) // Not searching upwards and we have a below turf.
T = T.below // Consider the turf below us as well. (Z-lights)
goto check_t
else // Not searching upwards and we don't have a below turf.
zlights_going_up = TRUE
T = originalT
goto zlight_check
// Upwards lights are handled at the corner level, so only search down.
if (T && (T.flags & MIMIC_BELOW) && T.below)
T = T.below
goto check_t
END_FOR_DVIEW
@@ -73,7 +73,7 @@
check_t:
if (T.dynamic_lighting || T.light_sources)
if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources)
Tcorners = T.corners
if (!T.lighting_corners_initialised)
T.lighting_corners_initialised = TRUE
+1 -1
View File
@@ -49,7 +49,7 @@ var/list/admin_verbs_lighting = list(
if (!check_rights(R_DEBUG|R_DEV)) return
if (!T.dynamic_lighting)
if (TURF_IS_DYNAMICALLY_LIT(T))
src << "That turf is not dynamically lit."
return