mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
General Lighting Improvements (#3482)
changes: Z-lights can now shine both upwards and downwards. Z-lights will now get less intense with each zlevel traversed. Sunlight no longer has distance falloff. Minor optimizations/simplification for directional lighting.
This commit is contained in:
@@ -34,7 +34,6 @@
|
||||
var/tmp/cached_origin_x // The last known X coord of the origin.
|
||||
var/tmp/cached_origin_y // The last known Y coord of the origin.
|
||||
var/tmp/old_direction // The last known direction of the origin.
|
||||
var/tmp/targ_sign // The sign to test the point against.
|
||||
var/tmp/test_x_offset // How much the X coord should be offset due to direction.
|
||||
var/tmp/test_y_offset // How much the Y coord should be offset due to direction.
|
||||
var/tmp/facing_opaque = FALSE
|
||||
@@ -46,6 +45,8 @@
|
||||
|
||||
var/needs_update = LIGHTING_NO_UPDATE
|
||||
|
||||
var/skip_falloff = FALSE // ONLY for use with sunlight, behavior is undefined if TRUE on regular sources.
|
||||
|
||||
/datum/light_source/New(atom/owner, atom/top)
|
||||
source_atom = owner // Set our new owner.
|
||||
|
||||
@@ -68,8 +69,6 @@
|
||||
|
||||
//L_PROF(source_atom, "source_new([type])")
|
||||
|
||||
return ..()
|
||||
|
||||
// Kill ourselves.
|
||||
/datum/light_source/Destroy(force)
|
||||
//L_PROF(source_atom, "source_destroy")
|
||||
@@ -159,31 +158,19 @@
|
||||
#define MINMAX(NUM) ((NUM) < 0 ? -round(-(NUM)) : round(NUM))
|
||||
#define ARBITRARY_NUMBER 10
|
||||
|
||||
/datum/light_source/proc/update_angle()
|
||||
var/turf/T = get_turf(top_atom)
|
||||
|
||||
var/ndir
|
||||
if (istype(top_atom, /mob) && top_atom:facing_dir)
|
||||
ndir = top_atom:facing_dir
|
||||
else
|
||||
ndir = top_atom.dir
|
||||
|
||||
// Don't do anything if nothing is different, trig ain't free.
|
||||
if (T.x == cached_origin_x && T.y == cached_origin_y && old_direction == ndir)
|
||||
return
|
||||
|
||||
/datum/light_source/proc/regenerate_angle(ndir)
|
||||
old_direction = ndir
|
||||
|
||||
var/turf/front = get_step(T, old_direction)
|
||||
var/turf/front = get_step(source_turf, old_direction)
|
||||
facing_opaque = (front && front.has_opaque_atom)
|
||||
|
||||
cached_origin_x = test_x_offset = T.x
|
||||
cached_origin_y = test_y_offset = T.y
|
||||
cached_origin_x = test_x_offset = source_turf.x
|
||||
cached_origin_y = test_y_offset = source_turf.y
|
||||
|
||||
if (facing_opaque)
|
||||
return
|
||||
|
||||
var/angle = light_angle / 2
|
||||
var/angle = light_angle * 0.5
|
||||
switch (old_direction)
|
||||
if (NORTH)
|
||||
limit_a_t = angle + 90
|
||||
@@ -214,8 +201,6 @@
|
||||
limit_b_x = MINMAX(limit_b_x)
|
||||
limit_b_y = POLAR_TO_CART_Y(light_range + ARBITRARY_NUMBER, limit_b_t)
|
||||
limit_b_y = MINMAX(limit_b_y)
|
||||
// This won't change unless the origin or dir changes, might as well do it here.
|
||||
targ_sign = PSEUDO_WEDGE(limit_a_x, limit_a_y, limit_b_x, limit_b_y) > 0
|
||||
|
||||
#undef ARBITRARY_NUMBER
|
||||
#undef POLAR_TO_CART_X
|
||||
@@ -248,7 +233,16 @@
|
||||
|
||||
var/actual_range = light_range
|
||||
|
||||
APPLY_CORNER(C,now)
|
||||
var/Sx = source_turf.x
|
||||
var/Sy = source_turf.y
|
||||
var/Sz = source_turf.z
|
||||
|
||||
if (skip_falloff)
|
||||
APPLY_CORNER_SIMPLE(C)
|
||||
else
|
||||
var/height = C.z == Sz ? LIGHTING_HEIGHT : CALCULATE_CORNER_HEIGHT(C.z, Sz)
|
||||
APPLY_CORNER(C, now, Sx, Sy, height)
|
||||
|
||||
UNSETEMPTY(effect_str)
|
||||
|
||||
// If you update this, update the equivalent proc in lighting_source_novis.dm.
|
||||
@@ -305,11 +299,36 @@
|
||||
light_angle = source_atom.light_wedge
|
||||
update = TRUE
|
||||
|
||||
if (light_angle && top_atom.dir != old_direction)
|
||||
update = TRUE
|
||||
if (light_angle)
|
||||
var/ndir
|
||||
if (istype(top_atom, /mob) && top_atom:facing_dir)
|
||||
ndir = top_atom:facing_dir
|
||||
else
|
||||
ndir = top_atom.dir
|
||||
|
||||
if (update && light_angle)
|
||||
update_angle()
|
||||
if (old_direction != ndir) // If our direction has changed, we need to regenerate all the angle info.
|
||||
regenerate_angle(ndir)
|
||||
update = TRUE
|
||||
else // Check if it was just a x/y translation, and update our vars without an regenerate_angle() call if it is.
|
||||
var/co_updated = FALSE
|
||||
if (source_turf.x != cached_origin_x)
|
||||
test_x_offset += source_turf.x - cached_origin_x
|
||||
cached_origin_x = source_turf.x
|
||||
|
||||
co_updated = TRUE
|
||||
|
||||
if (source_turf.y != cached_origin_y)
|
||||
test_y_offset += source_turf.y - cached_origin_y
|
||||
cached_origin_y = source_turf.y
|
||||
|
||||
co_updated = TRUE
|
||||
|
||||
if (co_updated)
|
||||
// We might be facing a wall now.
|
||||
var/turf/front = get_step(source_turf, old_direction)
|
||||
facing_opaque = (front && front.has_opaque_atom)
|
||||
|
||||
update = TRUE
|
||||
|
||||
if (update)
|
||||
needs_update = LIGHTING_CHECK_UPDATE
|
||||
@@ -324,11 +343,18 @@
|
||||
var/list/Tcorners
|
||||
var/Sx = source_turf.x
|
||||
var/Sy = source_turf.y
|
||||
var/Sz = source_turf.z
|
||||
var/corner_height = LIGHTING_HEIGHT
|
||||
var/actual_range = (light_angle && facing_opaque) ? light_range * LIGHTING_BLOCKED_FACTOR : light_range
|
||||
var/test_x
|
||||
var/test_y
|
||||
|
||||
FOR_DVIEW(T, Ceiling(actual_range), source_turf, 0)
|
||||
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
|
||||
check_t:
|
||||
|
||||
if (light_angle && !facing_opaque) // Directional lighting coordinate filter.
|
||||
@@ -336,7 +362,7 @@
|
||||
test_y = T.y - test_y_offset
|
||||
|
||||
// if the signs of both of these are NOT the same, the point is NOT within the cone.
|
||||
if (((PSEUDO_WEDGE(limit_a_x, limit_a_y, test_x, test_y) > 0) != targ_sign) || ((PSEUDO_WEDGE(test_x, test_y, limit_b_x, limit_b_y) > 0) != targ_sign))
|
||||
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)
|
||||
@@ -362,9 +388,21 @@
|
||||
|
||||
turfs += T
|
||||
|
||||
if (isopenturf(T) && T:below)
|
||||
T = T:below // Consider the turf below us as well. (Z-lights)
|
||||
goto check_t
|
||||
// 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 (isopenturf(T) && 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
|
||||
|
||||
END_FOR_DVIEW
|
||||
|
||||
@@ -391,7 +429,7 @@
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER_XY(C, now, Sx, Sy)
|
||||
APPLY_CORNER_BY_HEIGHT(now)
|
||||
else
|
||||
L = corners - effect_str
|
||||
for (thing in L)
|
||||
@@ -401,7 +439,7 @@
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER_XY(C, now, Sx, Sy)
|
||||
APPLY_CORNER_BY_HEIGHT(now)
|
||||
|
||||
for (thing in corners - L)
|
||||
C = thing
|
||||
@@ -409,7 +447,7 @@
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER_XY(C, now, Sx, Sy)
|
||||
APPLY_CORNER_BY_HEIGHT(now)
|
||||
|
||||
L = effect_str - corners
|
||||
for (thing in L)
|
||||
|
||||
Reference in New Issue
Block a user