diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index ca02d14e4cea..e7b30dabee4a 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -50,3 +50,27 @@ #define FLASH_LIGHT_DURATION 2 #define FLASH_LIGHT_POWER 3 #define FLASH_LIGHT_RANGE 3.8 + +/// Returns the red part of a #RRGGBB hex sequence as number +#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4)) + +/// Returns the green part of a #RRGGBB hex sequence as number +#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6)) + +/// Returns the blue part of a #RRGGBB hex sequence as number +#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8)) + +/// Parse the hexadecimal color into lumcounts of each perspective. +#define PARSE_LIGHT_COLOR(source) \ +do { \ + if (source.light_color) { \ + var/__light_color = source.light_color; \ + source.lum_r = GETREDPART(__light_color) / 255; \ + source.lum_g = GETGREENPART(__light_color) / 255; \ + source.lum_b = GETBLUEPART(__light_color) / 255; \ + } else { \ + source.lum_r = 1; \ + source.lum_g = 1; \ + source.lum_b = 1; \ + }; \ +} while (FALSE) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index d11e96ce946c..d07f24b357f8 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -426,22 +426,6 @@ return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) -/proc/GetRedPart(const/hexa) - return hex2num(copytext(hexa,2,4)) - -/proc/GetGreenPart(const/hexa) - return hex2num(copytext(hexa,4,6)) - -/proc/GetBluePart(const/hexa) - return hex2num(copytext(hexa,6,8)) - -/proc/GetHexColors(const/hexa) - return list( - GetRedPart(hexa), - GetGreenPart(hexa), - GetBluePart(hexa) - ) - /proc/MixColors(const/list/colors) var/list/reds = list() var/list/blues = list() @@ -449,9 +433,9 @@ var/list/weights = list() for (var/i = 0, ++i <= colors.len) - reds.Add(GetRedPart(colors[i])) - blues.Add(GetBluePart(colors[i])) - greens.Add(GetGreenPart(colors[i])) + reds.Add(GETREDPART(colors[i])) + blues.Add(GETBLUEPART(colors[i])) + greens.Add(GETGREENPART(colors[i])) weights.Add(1) var/r = mixOneColor(weights, reds) diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 541d5b1aafd0..e5ce812c0a6e 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -1,7 +1,3 @@ -var/global/list/lighting_update_lights = list() // List of lighting sources queued for update. -var/global/list/lighting_update_corners = list() // List of lighting corners queued for update. -var/global/list/lighting_update_objects = list() // List of lighting objects queued for update. - SUBSYSTEM_DEF(lighting) name = "Lighting" @@ -11,8 +7,12 @@ SUBSYSTEM_DEF(lighting) flags = SS_TICKER msg_lobby = "Включаем свет..." + var/static/list/sources_queue = list() // List of lighting sources queued for update. + var/static/list/corners_queue = list() // List of lighting corners queued for update. + var/static/list/objects_queue = list() // List of lighting objects queued for update. + /datum/controller/subsystem/lighting/stat_entry() - ..("L:[global.lighting_update_lights.len]|C:[global.lighting_update_corners.len]|O:[global.lighting_update_objects.len]") + ..("L:[sources_queue.len]|C:[corners_queue.len]|O:[objects_queue.len]") /datum/controller/subsystem/lighting/Initialize(timeofday) if(!initialized) @@ -48,9 +48,9 @@ SUBSYSTEM_DEF(lighting) if(!init_fire) MC_SPLIT_TICK - while (global.lighting_update_lights.len) - var/datum/light_source/L = global.lighting_update_lights[global.lighting_update_lights.len] - global.lighting_update_lights.len-- + while (sources_queue.len) + var/datum/light_source/L = sources_queue[sources_queue.len] + sources_queue.len-- L.update_corners() @@ -67,25 +67,25 @@ SUBSYSTEM_DEF(lighting) var/i = 0 - for (i in 1 to global.lighting_update_corners.len) - var/datum/lighting_corner/C = global.lighting_update_corners[i] + for (i in 1 to corners_queue.len) + var/datum/lighting_corner/C = corners_queue[i] - C.update_objects() C.needs_update = FALSE + C.update_objects() if(init_fire) CHECK_TICK else if (MC_TICK_CHECK) break if (i) - global.lighting_update_corners.Cut(1, i+1) + corners_queue.Cut(1, i+1) i = 0 if(!init_fire) MC_SPLIT_TICK - for (i in 1 to global.lighting_update_objects.len) - var/atom/movable/lighting_object/O = global.lighting_update_objects[i] + for (i in 1 to objects_queue.len) + var/atom/movable/lighting_object/O = objects_queue[i] if (QDELETED(O)) continue @@ -97,7 +97,7 @@ SUBSYSTEM_DEF(lighting) else if (MC_TICK_CHECK) break if (i) - global.lighting_update_objects.Cut(1, i+1) + objects_queue.Cut(1, i+1) /datum/controller/subsystem/lighting/Recover() initialized = SSlighting.initialized diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 3f9d5593c340..3289fef87259 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -1,5 +1,7 @@ /turf icon = 'icons/turf/floors.dmi' + luminosity = 1 + var/turf/basetype = /turf/environment/space var/can_deconstruct = FALSE @@ -39,6 +41,20 @@ var/list/turf_decals + var/dynamic_lighting = TRUE + var/force_lighting_update = FALSE + + var/tmp/lighting_corners_initialised = FALSE + + ///Our lighting object. + var/tmp/atom/movable/lighting_object/lighting_object + ///Lighting Corner datums. + var/tmp/datum/lighting_corner/lighting_corner_NE + var/tmp/datum/lighting_corner/lighting_corner_SE + var/tmp/datum/lighting_corner/lighting_corner_SW + var/tmp/datum/lighting_corner/lighting_corner_NW + + var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. /** * Turf Initialize @@ -321,9 +337,11 @@ var/old_opacity = opacity var/old_dynamic_lighting = dynamic_lighting var/old_force_lighting_update = force_lighting_update - var/old_affecting_lights = affecting_lights var/old_lighting_object = lighting_object - var/old_corners = corners + var/old_lighting_corner_NE = lighting_corner_NE + var/old_lighting_corner_SE = lighting_corner_SE + var/old_lighting_corner_SW = lighting_corner_SW + var/old_lighting_corner_NW = lighting_corner_NW var/old_basetype = basetype var/old_flooded = flooded @@ -400,11 +418,15 @@ queue_smooth_neighbors(W) + lighting_corner_NE = old_lighting_corner_NE + lighting_corner_SE = old_lighting_corner_SE + lighting_corner_SW = old_lighting_corner_SW + lighting_corner_NW = old_lighting_corner_NW + if(SSlighting.initialized) recalc_atom_opacity() lighting_object = old_lighting_object - affecting_lights = old_affecting_lights - corners = old_corners + if (force_lighting_update || old_force_lighting_update || old_opacity != opacity || dynamic_lighting != old_dynamic_lighting) reconsider_lights() diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 75ac45bf13aa..51da19a11de1 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -2,17 +2,16 @@ // 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. -var/global/list/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/turf/master_NE + var/turf/master_SE + var/turf/master_SW + var/turf/master_NW var/lum_r = 0 var/lum_g = 0 @@ -27,9 +26,7 @@ var/global/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, /datum/lighting_corner/New(turf/new_turf, diagonal) . = ..() - masters = list() - masters[new_turf] = turn(diagonal, 180) - z = new_turf.z + save_master(new_turf, turn(diagonal, 180)) 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. @@ -41,53 +38,52 @@ var/global/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, // 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 = global.LIGHTING_CORNER_DIAGONAL.Find(turn(diagonal, 180)) - T.corners[i] = src + save_master(T, diagonal) // 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 = global.LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180)) - T.corners[i] = src + save_master(T, ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates. // 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 = global.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 + save_master(T, ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates. + +/datum/lighting_corner/proc/save_master(turf/master, dir) + switch (dir) + if (NORTHEAST) + master_NE = master + master.lighting_corner_SW = src + if (SOUTHEAST) + master_SE = master + master.lighting_corner_NW = src + if (SOUTHWEST) + master_SW = master + master.lighting_corner_NE = src + if (NORTHWEST) + master_NW = master + master.lighting_corner_SE = src + +/datum/lighting_corner/proc/self_destruct_if_idle() + if (!length(affecting)) + qdel(src, force = TRUE) + +/datum/lighting_corner/proc/vis_update() + for (var/datum/light_source/light_source as anything in affecting) + light_source.vis_update() + +/datum/lighting_corner/proc/full_update() + for (var/datum/light_source/light_source as anything in affecting) + light_source.recalc_corner(src) // 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) + if (!(delta_r || delta_g || delta_b)) // 0 is falsey ok return lum_r += delta_r @@ -96,10 +92,10 @@ var/global/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, if (!needs_update) needs_update = TRUE - global.lighting_update_corners += src + 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. + // Cache these values ahead 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 @@ -122,22 +118,52 @@ var/global/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, #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 - global.lighting_update_objects += T.lighting_object - + var/atom/movable/lighting_object/lighting_object = master_NE?.lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_SE?.lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_SW?.lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_NW?.lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + self_destruct_if_idle() /datum/lighting_corner/dummy/New() return - /datum/lighting_corner/Destroy(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% retarded and needs his head checked. Thanks. Send them my regards by the way.") + for (var/datum/light_source/light_source as anything in affecting) + LAZYREMOVE(light_source.effect_str, src) + affecting = null + + if (master_NE) + master_NE.lighting_corner_SW = null + master_NE.lighting_corners_initialised = FALSE + if (master_SE) + master_SE.lighting_corner_NW = null + master_SE.lighting_corners_initialised = FALSE + if (master_SW) + master_SW.lighting_corner_NE = null + master_SW.lighting_corners_initialised = FALSE + if (master_NW) + master_NW.lighting_corner_SE = null + master_NW.lighting_corners_initialised = FALSE + if (needs_update) + SSlighting.corners_queue -= src return ..() diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 87684a836a63..5e40d75c1743 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -31,11 +31,11 @@ S.update_starlight() needs_update = TRUE - global.lighting_update_objects += src + SSlighting.objects_queue += src /atom/movable/lighting_object/Destroy(force) if (force) - global.lighting_update_objects -= src + SSlighting.objects_queue -= src if (loc != myturf) var/turf/oldturf = get_turf(myturf) var/turf/newturf = get_turf(loc) @@ -71,16 +71,10 @@ // 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/list/corners = myturf.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 = corners[3] || dummy_lighting_corner - cg = corners[2] || dummy_lighting_corner - cb = corners[4] || dummy_lighting_corner - ca = corners[1] || dummy_lighting_corner + var/datum/lighting_corner/cr = myturf.lighting_corner_SW || dummy_lighting_corner + var/datum/lighting_corner/cg = myturf.lighting_corner_SE || dummy_lighting_corner + var/datum/lighting_corner/cb = myturf.lighting_corner_NW || dummy_lighting_corner + var/datum/lighting_corner/ca = myturf.lighting_corner_NE || dummy_lighting_corner var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 523e08970161..147fe7a0851e 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -22,7 +22,6 @@ var/tmp/applied_lum_b var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners. - var/list/turf/affecting_turfs var/applied = FALSE // Whether we have applied our light yet or not. @@ -43,12 +42,10 @@ light_range = source_atom.light_range light_color = source_atom.light_color - parse_light_color() + PARSE_LIGHT_COLOR(src) update() - return ..() - /datum/light_source/Destroy(force) remove_lum() @@ -60,7 +57,12 @@ LAZYREMOVE(top_atom.light_sources, src) if (needs_update) - global.lighting_update_lights -= src + SSlighting.sources_queue -= src + + top_atom = null + source_atom = null + source_turf = null + pixel_turf = null return ..() @@ -69,7 +71,7 @@ // Actually that'd be great if you could! #define EFFECT_UPDATE(level) \ if (needs_update == LIGHTING_NO_UPDATE) \ - global.lighting_update_lights += src; \ + SSlighting.sources_queue += src; \ if (needs_update < level) \ needs_update = level; \ @@ -96,17 +98,6 @@ /datum/light_source/proc/vis_update() EFFECT_UPDATE(LIGHTING_VIS_UPDATE) -// Decompile the hexadecimal colour into lumcounts of each perspective. -/datum/light_source/proc/parse_light_color() - if (light_color) - lum_r = GetRedPart (light_color) / 255 - lum_g = GetGreenPart (light_color) / 255 - lum_b = GetBluePart (light_color) / 255 - else - lum_r = 1 - lum_g = 1 - lum_b = 1 - // Macro that applies light to a new corner. // It is a macro in the interest of speed, yet not having to copy paste it. // If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line. @@ -114,45 +105,34 @@ // 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; \ - var/OLD = effect_str[C]; \ - effect_str[C] = .; \ - \ - C.update_lumcount \ - ( \ - (. * lum_r) - (OLD * applied_lum_r), \ - (. * lum_g) - (OLD * applied_lum_g), \ - (. * lum_b) - (OLD * applied_lum_b) \ - ); - -#define REMOVE_CORNER(C) \ - . = -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]; \ + \ + C.update_lumcount \ + ( \ + (. * lum_r) - (OLD * applied_lum_r), \ + (. * lum_g) - (OLD * applied_lum_g), \ + (. * lum_b) - (OLD * 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/remove_lum() applied = FALSE - var/thing - for (thing in affecting_turfs) - var/turf/T = thing - LAZYREMOVE(T.affecting_lights, src) - - affecting_turfs = null - - var/datum/lighting_corner/C - for (thing in effect_str) - C = thing - REMOVE_CORNER(C) - - LAZYREMOVE(C.affecting, src) + for (var/datum/lighting_corner/corner as anything in effect_str) + REMOVE_CORNER(corner) + LAZYREMOVE(corner.affecting, src) effect_str = null @@ -163,7 +143,8 @@ effect_str[C] = 0 APPLY_CORNER(C) - UNSETEMPTY(effect_str) + effect_str[C] = . + /datum/light_source/proc/update_corners() var/update = FALSE @@ -214,7 +195,7 @@ if (source_atom.light_color != light_color) light_color = source_atom.light_color - parse_light_color() + PARSE_LIGHT_COLOR(src) update = TRUE else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b) @@ -230,71 +211,55 @@ var/list/datum/lighting_corner/corners = list() var/list/turf/turfs = list() - var/thing - var/datum/lighting_corner/C - var/turf/T + if (source_turf) var/oldlum = source_turf.luminosity source_turf.luminosity = CEILING(light_range, 1) - for(T in view(CEILING(light_range, 1), source_turf)) - for (thing in T.get_corners(source_turf)) - C = thing - corners[C] = 0 + for(var/turf/T in view(CEILING(light_range, 1), source_turf)) + if(!T.has_opaque_atom) + if (!T.lighting_corners_initialised) + T.generate_missing_corners() + corners[T.lighting_corner_NE] = 0 + corners[T.lighting_corner_SE] = 0 + corners[T.lighting_corner_SW] = 0 + corners[T.lighting_corner_NW] = 0 turfs += T source_turf.luminosity = oldlum - 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) - T = thing - LAZYADD(T.affecting_lights, src) - - L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights. - affecting_turfs -= L - for (thing in L) - T = thing - LAZYREMOVE(T.affecting_lights, src) - + var/list/datum/lighting_corner/new_corners = (corners - effect_str) LAZYINITLIST(effect_str) if (needs_update == LIGHTING_VIS_UPDATE) - for (thing in corners - effect_str) // New corners - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - APPLY_CORNER(C) + for (var/datum/lighting_corner/corner as anything in new_corners) + APPLY_CORNER(corner) + if (. != 0) + LAZYADD(corner.affecting, src) + effect_str[corner] = . else - L = corners - effect_str - for (thing in L) // New corners - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - APPLY_CORNER(C) - - for (thing in corners - L) // Existing corners - C = thing - if (!C.active) - effect_str[C] = 0 - continue - APPLY_CORNER(C) - - L = effect_str - corners - for (thing in L) // Old, now gone, corners. - C = thing - REMOVE_CORNER(C) - LAZYREMOVE(C.affecting, src) - effect_str -= L + for (var/datum/lighting_corner/corner as anything in new_corners) + APPLY_CORNER(corner) + if (. != 0) + LAZYADD(corner.affecting, src) + effect_str[corner] = . + + for (var/datum/lighting_corner/corner as anything in corners - new_corners) // Existing corners + APPLY_CORNER(corner) + if (. != 0) + effect_str[corner] = . + else + LAZYREMOVE(corner.affecting, src) + effect_str -= corner + + var/list/datum/lighting_corner/gone_corners = effect_str - corners + for (var/datum/lighting_corner/corner as anything in gone_corners) + REMOVE_CORNER(corner) + LAZYREMOVE(corner.affecting, src) + effect_str -= gone_corners 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 diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 2cf19f430993..f0416d4b71dc 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -1,35 +1,14 @@ -/turf - var/dynamic_lighting = TRUE - var/force_lighting_update = FALSE - luminosity = 1 - - var/tmp/lighting_corners_initialised = FALSE - - var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf. - var/tmp/atom/movable/lighting_object/lighting_object // Our lighting object. - var/tmp/list/datum/lighting_corner/corners - var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. - // Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() - var/datum/light_source/L - var/thing - for (thing in affecting_lights) - L = thing - L.vis_update() + lighting_corner_NE?.vis_update() + lighting_corner_SE?.vis_update() + lighting_corner_SW?.vis_update() + lighting_corner_NW?.vis_update() /turf/proc/lighting_clear_overlay() if (lighting_object) qdel(lighting_object, TRUE) - var/datum/lighting_corner/C - var/thing - for (thing in corners) - if(!thing) - continue - C = thing - C.update_active() - // Builds a lighting object for us, but only if our area is dynamic. /turf/proc/lighting_build_overlay() if (lighting_object) @@ -39,37 +18,28 @@ if (!IS_DYNAMIC_LIGHTING(A) && !light_sources) return - if (!lighting_corners_initialised) - generate_missing_corners() - new/atom/movable/lighting_object(src) - var/thing - var/datum/lighting_corner/C - var/datum/light_source/S - for (thing in corners) - if(!thing) - continue - C = thing - if (!C.active) // We would activate the corner, calculate the lighting for it. - for (thing in C.affecting) - S = thing - S.recalc_corner(C) - C.active = TRUE - // Used to get a scaled lumcount. /turf/proc/get_lumcount(minlum = 0, maxlum = 1) if (!lighting_object) return 1 var/totallums = 0 - var/thing var/datum/lighting_corner/L - for (thing in corners) - if(!thing) - continue - L = thing + L = lighting_corner_NE + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_SE + if (L) totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_SW + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_NW + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + totallums /= 12 // 4 corners, each with 3 channels, get the average. @@ -104,28 +74,20 @@ else lighting_clear_overlay() -/turf/proc/get_corners() - if (!IS_DYNAMIC_LIGHTING(src) && !light_sources) - 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) && !light_sources) - return + if (!lighting_corner_NE) + lighting_corner_NE = new/datum/lighting_corner(src, NORTH|EAST) + + if (!lighting_corner_SE) + lighting_corner_SE = new/datum/lighting_corner(src, SOUTH|EAST) + + if (!lighting_corner_SW) + lighting_corner_SW = new/datum/lighting_corner(src, SOUTH|WEST) + + if (!lighting_corner_NW) + lighting_corner_NW = new/datum/lighting_corner(src, NORTH|WEST) + lighting_corners_initialised = TRUE - if (!corners) - corners = list(null, null, null, null) - - for (var/i = 1 to 4) - if (corners[i]) // Already have a corner on this direction. - continue - - corners[i] = new/datum/lighting_corner(src, global.LIGHTING_CORNER_DIAGONAL[i]) /turf/proc/set_dynamic_lighting(new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED) if (new_dynamic_lighting == dynamic_lighting)