More /vg/lighting tweaks

Rather then remove the light from all tiles, then re-add the light to all tiles, we just go thru each tile and diff the light level from the last value we added to it. (since this is tracked)
This cut the proc calls for updating lights in half.

Lighting objects now default to full brite rather then full dark so shuttles aren't as immersion breaking when they transit.

Made lighting more agressive about clearing empty lists.
This commit is contained in:
MrStonedOne
2017-05-06 01:50:19 -07:00
parent e4ed4d0e5e
commit 2ed266d506
7 changed files with 152 additions and 136 deletions
+12 -5
View File
@@ -16,10 +16,10 @@
#define LIGHTING_BASE_MATRIX \
list \
( \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
1, 1, 1, 0, \
1, 1, 1, 0, \
1, 1, 1, 0, \
1, 1, 1, 0, \
0, 0, 0, 1 \
) \
@@ -78,4 +78,11 @@
#define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled
#define DYNAMIC_LIGHTING_FORCED 2 //dynamic lighting enabled even if the area doesn't require power
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3 //dynamic lighting enabled only if starlight is.
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
//code assumes higher numbers override lower numbers.
#define LIGHTING_NO_UPDATE 0
#define LIGHTING_VIS_UPDATE 1
#define LIGHTING_CHECK_UPDATE 2
#define LIGHTING_FORCE_UPDATE 3
+2 -10
View File
@@ -36,18 +36,10 @@ SUBSYSTEM_DEF(lighting)
for (i in 1 to GLOB.lighting_update_lights.len)
var/datum/light_source/L = GLOB.lighting_update_lights[i]
if (L.check() || QDELETED(L) || L.force_update)
L.remove_lum()
if (!QDELETED(L))
L.apply_lum()
L.update_corners()
else if (L.vis_update) //We smartly update only tiles that became (in) visible to use.
L.smart_vis_update()
L.needs_update = LIGHTING_NO_UPDATE
L.vis_update = FALSE
L.force_update = FALSE
L.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
-2
View File
@@ -25,8 +25,6 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
var/cache_b = LIGHTING_SOFT_THRESHOLD
var/cache_mx = 0
var/update_gen = 0
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
. = ..()
+15 -9
View File
@@ -6,6 +6,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
anchored = TRUE
icon = LIGHTING_ICON
icon_state = "transparent"
color = LIGHTING_BASE_MATRIX
plane = LIGHTING_PLANE
mouse_opacity = 0
@@ -16,7 +17,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
var/needs_update = FALSE
/atom/movable/lighting_object/Initialize(mapload, var/no_update = FALSE)
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
GLOB.all_lighting_objects += src
@@ -28,10 +29,8 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
if (no_update)
return
update()
needs_update = TRUE
GLOB.lighting_update_objects += src
/atom/movable/lighting_object/Destroy(var/force)
if (force)
@@ -69,10 +68,17 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
// See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are.
var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new
var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner
var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner
var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner
var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner
var/list/corners = T.corners
var/datum/lighting_corner/cr = dummy_lighting_corner
var/datum/lighting_corner/cg = dummy_lighting_corner
var/datum/lighting_corner/cb = dummy_lighting_corner
var/datum/lighting_corner/ca = dummy_lighting_corner
if (corners) //done this way for speed
cr = T.corners[3] || dummy_lighting_corner
cg = T.corners[2] || dummy_lighting_corner
cb = T.corners[4] || dummy_lighting_corner
ca = T.corners[1] || dummy_lighting_corner
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
+1 -1
View File
@@ -8,6 +8,6 @@
if(!IS_DYNAMIC_LIGHTING(T))
continue
new/atom/movable/lighting_object(T, TRUE)
new/atom/movable/lighting_object(T)
CHECK_TICK
CHECK_TICK
+116 -109
View File
@@ -26,22 +26,15 @@
var/applied = FALSE // Whether we have applied our light yet or not.
var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became (in)visible to us.
var/needs_update // Whether we are queued for an update.
var/force_update
var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update.
/datum/light_source/New(var/atom/owner, var/atom/top)
source_atom = owner // Set our new owner.
if (!source_atom.light_sources)
source_atom.light_sources = list()
source_atom.light_sources += src // Add us to the lights of our owner.
LAZYADD(source_atom.light_sources, src)
top_atom = top
if (top_atom != source_atom)
if (!top.light_sources)
top.light_sources = list()
top_atom.light_sources += src
LAZYADD(top_atom.light_sources, src)
source_turf = top_atom
pixel_turf = get_turf_pixel(top_atom) || source_turf
@@ -52,20 +45,18 @@
parse_light_color()
effect_str = list()
affecting_turfs = list()
update()
return ..()
/datum/light_source/Destroy(force)
force_update()
remove_lum()
if (source_atom)
source_atom.light_sources -= src
LAZYREMOVE(source_atom.light_sources, src)
if (top_atom)
top_atom.light_sources -= src
LAZYREMOVE(top_atom.light_sources, src)
. = ..()
if(!force)
return QDEL_HINT_IWILLGC
@@ -73,79 +64,34 @@
// Yes this doesn't align correctly on anything other than 4 width tabs.
// If you want it to go switch everybody to elastic tab stops.
// Actually that'd be great if you could!
#define EFFECT_UPDATE \
if (!needs_update) \
{ \
GLOB.lighting_update_lights += src; \
needs_update = TRUE; \
}
#define EFFECT_UPDATE(level) \
if (needs_update == LIGHTING_NO_UPDATE) \
GLOB.lighting_update_lights += src; \
if (needs_update < level) \
needs_update = level; \
// This proc will cause the light source to update the top atom, and add itself to the update queue.
/datum/light_source/proc/update(var/atom/new_top_atom)
// This top atom is different.
if (new_top_atom && new_top_atom != top_atom)
if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom.
top_atom.light_sources -= src
LAZYREMOVE(top_atom.light_sources, src)
top_atom = new_top_atom
if (top_atom != source_atom)
LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom.
EFFECT_UPDATE
EFFECT_UPDATE(LIGHTING_CHECK_UPDATE)
// Will force an update without checking if it's actually needed.
/datum/light_source/proc/force_update()
force_update = 1
EFFECT_UPDATE
EFFECT_UPDATE(LIGHTING_FORCE_UPDATE)
// Will cause the light source to recalculate turfs that were removed or added to visibility only.
/datum/light_source/proc/vis_update()
vis_update = 1
EFFECT_UPDATE
// Will check if we actually need to update, and update any variables that may need to be updated.
/datum/light_source/proc/check()
if (!source_atom || !light_range || !light_power)
qdel(src)
return 1
if (!top_atom)
top_atom = source_atom
. = 1
if (isturf(top_atom))
if (source_turf != top_atom)
source_turf = top_atom
pixel_turf = source_turf
. = 1
else if (top_atom.loc != source_turf)
source_turf = top_atom.loc
pixel_turf = get_turf_pixel(top_atom)
. = 1
else
var/P = get_turf_pixel(top_atom)
if (P != pixel_turf)
. = 1
pixel_turf = get_turf_pixel(top_atom)
if (source_atom.light_power != light_power)
light_power = source_atom.light_power
. = 1
if (source_atom.light_range != light_range)
light_range = source_atom.light_range
. = 1
if (light_range && light_power && !applied)
. = 1
if (source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
. = 1
EFFECT_UPDATE(LIGHTING_VIS_UPDATE)
// Decompile the hexadecimal colour into lumcounts of each perspective.
/datum/light_source/proc/parse_light_color()
@@ -164,48 +110,47 @@
// As such this all gets counted as a single line.
// The braces and semicolons are there to be able to do this on a single line.
#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
#define APPLY_CORNER(C) \
. = LUM_FALLOFF(C, pixel_turf); \
\
. *= light_power; \
\
effect_str[C] = .; \
\
C.update_lumcount \
( \
. * applied_lum_r, \
. * applied_lum_g, \
. * applied_lum_b \
#define APPLY_CORNER(C) \
. = LUM_FALLOFF(C, pixel_turf); \
. *= light_power; \
var/OLD = effect_str[C]; \
\
effect_str[C] = .; \
\
C.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_g) - (OLD * applied_lum_g) \
);
// I don't need to explain what this does, do I?
#define REMOVE_CORNER(C) \
. = -effect_str[C]; \
C.update_lumcount \
( \
. * applied_lum_r, \
. * applied_lum_g, \
. * applied_lum_b \
#define REMOVE_CORNER(C) \
. = -effect_str[C]; \
C.update_lumcount \
( \
. * applied_lum_r, \
. * applied_lum_g, \
. * applied_lum_b \
);
// This is the define used to calculate falloff.
/*
/datum/light_source/proc/apply_lum()
var/static/update_gen = 1
applied = 1
// Keep track of the last applied lum values so that the lighting can be reversed
applied_lum_r = lum_r
applied_lum_g = lum_g
applied_lum_b = lum_b
var/thing
var/datum/lighting_corner/C
var/corners = list()
LAZYINITLIST(effect_str)
FOR_DVIEW(var/turf/T, light_range+1, source_turf, INVISIBILITY_LIGHTING)
if (!T.lighting_corners_initialised)
T.generate_missing_corners()
var/list/turf_corners = T.get_corners()
for (thing in T.get_corners())
for (thing in turf_corners)
C = thing
if (C.update_gen == update_gen)
continue
@@ -220,9 +165,13 @@
APPLY_CORNER(C)
LAZYADD(T.affecting_lights, src)
affecting_turfs += T
LAZYADD(affecting_turfs, T)
FOR_DVIEW_END
update_gen++
applied_lum_r = lum_r
applied_lum_g = lum_g
applied_lum_b = lum_b
*/
/datum/light_source/proc/remove_lum()
applied = FALSE
@@ -231,7 +180,7 @@
var/turf/T = thing
LAZYREMOVE(T.affecting_lights, src)
affecting_turfs.Cut()
affecting_turfs = null
var/datum/lighting_corner/C
for (thing in effect_str)
@@ -240,7 +189,7 @@
LAZYREMOVE(C.affecting, src)
effect_str.Cut()
effect_str = null
/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
if (effect_str.Find(C)) // Already have one.
@@ -248,22 +197,74 @@
APPLY_CORNER(C)
/datum/light_source/proc/smart_vis_update()
/datum/light_source/proc/update_corners()
var/update = FALSE
if (!source_atom)
qdel(src)
return
if (source_atom.light_power != light_power)
light_power = source_atom.light_power
update = TRUE
if (source_atom.light_range != light_range)
light_range = source_atom.light_range
update = TRUE
if (!top_atom)
top_atom = source_atom
update = TRUE
if (!light_range || !light_power)
qdel(src)
return
if (isturf(top_atom))
if (source_turf != top_atom)
source_turf = top_atom
pixel_turf = source_turf
update = TRUE
else if (top_atom.loc != source_turf)
source_turf = top_atom.loc
pixel_turf = get_turf_pixel(top_atom)
update = TRUE
else
var/P = get_turf_pixel(top_atom)
if (P != pixel_turf)
pixel_turf = get_turf_pixel(top_atom)
update = TRUE
if (light_range && light_power && !applied)
update = TRUE
if (source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
update = TRUE
else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b)
update = TRUE
if (update)
needs_update = LIGHTING_CHECK_UPDATE
else if (needs_update == LIGHTING_CHECK_UPDATE)
return //nothing's changed
var/list/datum/lighting_corner/corners = list()
var/list/turf/turfs = list()
var/thing
var/datum/lighting_corner/C
var/turf/T
FOR_DVIEW(T, light_range+1, source_turf, 0)
if (!T.lighting_corners_initialised)
T.generate_missing_corners()
FOR_DVIEW(T, Ceiling(light_range), source_turf, 0)
for (thing in T.get_corners(source_turf))
C = thing
corners[C] = 0
turfs += T
FOR_DVIEW_END
LAZYINITLIST(affecting_turfs)
var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them.
affecting_turfs += L
for (thing in L)
@@ -276,9 +277,8 @@
T = thing
LAZYREMOVE(T.affecting_lights, src)
for (thing in corners - effect_str) // New corners
LAZYINITLIST(effect_str)
for (thing in (needs_update == LIGHTING_VIS_UPDATE ? corners - effect_str : corners)) // New corners
C = thing
LAZYADD(C.affecting, src)
if (!C.active)
@@ -293,6 +293,13 @@
LAZYREMOVE(C.affecting, src)
effect_str -= C
applied_lum_r = lum_r
applied_lum_g = lum_g
applied_lum_b = lum_b
UNSETEMPTY(effect_str)
UNSETEMPTY(affecting_turfs)
#undef EFFECT_UPDATE
#undef LUM_FALLOFF
#undef REMOVE_CORNER
+6
View File
@@ -113,12 +113,18 @@
lighting_clear_overlay()
/turf/proc/get_corners()
if (!IS_DYNAMIC_LIGHTING(src))
return null
if (!lighting_corners_initialised)
generate_missing_corners()
if (has_opaque_atom)
return null // Since this proc gets used in a for loop, null won't be looped though.
return corners
/turf/proc/generate_missing_corners()
if (!IS_DYNAMIC_LIGHTING(src))
return
lighting_corners_initialised = TRUE
if (!corners)
corners = list(null, null, null, null)