Completely refactor planetary lighting (#8166)

This commit is contained in:
Cadyn
2024-04-19 16:08:00 +02:00
committed by GitHub
parent 76e5714ba4
commit 0418e5c8d4
15 changed files with 794 additions and 52 deletions
+127 -2
View File
@@ -5,6 +5,7 @@
/datum/lighting_corner
var/list/datum/light_source/affecting // Light sources affecting us.
var/sunlight = SUNLIGHT_NONE // CHOMPEdit
var/x = 0
var/y = 0
@@ -75,7 +76,7 @@
master.lighting_corner_SE = src
/datum/lighting_corner/proc/self_destruct_if_idle()
if (!LAZYLEN(affecting))
if (!LAZYLEN(affecting) && !sunlight) //CHOMPEdit
qdel(src, force = TRUE)
/datum/lighting_corner/proc/vis_update()
@@ -87,14 +88,28 @@
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)
/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b, var/from_sholder = FALSE) //CHOMPEdit
if (!(delta_r || delta_g || delta_b)) // 0 is falsey ok
return
//CHOMPEdit Begin
if((sunlight == SUNLIGHT_ONLY || sunlight == SUNLIGHT_ONLY_SHADE) && LAZYLEN(affecting))
change_sun()
if(sunlight == SUNLIGHT_ONLY || sunlight == SUNLIGHT_ONLY_SHADE)
//Okay fuck. If we're here some doodoo kaka bullshit happened (probably thanks to in-round map loading) and now the sunlight handler that owned us previously is fucking gone (real cool dude) so like try to get a new one ig
//Is this optimal? No. Is there a better way? Maybe. God knows I tried, but whatever fucking black magic is going on behind the scenes seems to defy all attempts at logic. So, if this works, it stays.
sunlight = SUNLIGHT_POSSIBLE
//CHOMPEdit End
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
//CHOMPEdit Begin
if(sunlight == SUNLIGHT_CURRENT && !LAZYLEN(affecting) && !from_sholder)
update_sunlight_handlers()
update_sunlight_handlers()
//CHOMPEdit End
if (!needs_update)
needs_update = TRUE
SSlighting.corners_queue += src
@@ -174,3 +189,113 @@
SSlighting.corners_queue -= src
return ..()
//CHOMPEdit Begin
/datum/lighting_corner/proc/update_sun(var/datum/planet_sunlight_handler/pshandler)
if(!pshandler)
return
if(sunlight == SUNLIGHT_ONLY)
lum_r = pshandler.red
lum_g = pshandler.green
lum_b = pshandler.blue
cache_r = pshandler.cache_r
cache_g = pshandler.cache_g
cache_b = pshandler.cache_b
largest_color_luminosity = pshandler.maxlum
if(sunlight == SUNLIGHT_ONLY_SHADE)
lum_r = pshandler.redshade
lum_g = pshandler.greenshade
lum_b = pshandler.blueshade
cache_r = pshandler.cache_r_shade
cache_g = pshandler.cache_g_shade
cache_b = pshandler.cache_b_shade
largest_color_luminosity = pshandler.maxlumshade
var/datum/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
/datum/lighting_corner/proc/change_sun()
lum_r = 0
lum_g = 0
lum_b = 0
var/turf/simulated/master_NE_sim = master_NE
var/turf/simulated/master_SE_sim = master_SE
var/turf/simulated/master_SW_sim = master_SW
var/turf/simulated/master_NW_sim = master_NW
if(istype(master_NE_sim) && master_NE_sim.shandler)
master_NE_sim.shandler.corner_sunlight_change(src)
if(istype(master_SE_sim) && master_SE_sim.shandler)
master_SE_sim.shandler.corner_sunlight_change(src)
if(istype(master_SW_sim) && master_SW_sim.shandler)
master_SW_sim.shandler.corner_sunlight_change(src)
if(istype(master_NW_sim) && master_NW_sim.shandler)
master_NW_sim.shandler.corner_sunlight_change(src)
update_sunlight_handlers()
/datum/lighting_corner/proc/update_sunlight_handlers()
var/turf/simulated/master_NE_sim = master_NE
var/turf/simulated/master_SE_sim = master_SE
var/turf/simulated/master_SW_sim = master_SW
var/turf/simulated/master_NW_sim = master_NW
if(istype(master_NE_sim) && master_NE_sim.shandler)
master_NE_sim.shandler.sunlight_update()
if(istype(master_SE_sim) && master_SE_sim.shandler)
master_SE_sim.shandler.sunlight_update()
if(istype(master_SW_sim) && master_SW_sim.shandler)
master_SW_sim.shandler.sunlight_update()
if(istype(master_NW_sim) && master_NW_sim.shandler)
master_NW_sim.shandler.sunlight_update()
/datum/lighting_corner/proc/all_onlysun()
var/datum/lighting_object/lighting_object = master_NE?.lighting_object
if (lighting_object && !(lighting_object.sunlight_only == sunlight))
return FALSE
lighting_object = master_SE?.lighting_object
if (lighting_object && !(lighting_object.sunlight_only == sunlight))
return FALSE
lighting_object = master_SW?.lighting_object
if (lighting_object && !(lighting_object.sunlight_only == sunlight))
return FALSE
lighting_object = master_NW?.lighting_object
if (lighting_object && !(lighting_object.sunlight_only == sunlight))
return FALSE
return TRUE
/datum/lighting_corner/proc/wake_sleepers()
var/turf/simulated/master_NE_sim = master_NE
var/turf/simulated/master_SE_sim = master_SE
var/turf/simulated/master_SW_sim = master_SW
var/turf/simulated/master_NW_sim = master_NW
if(istype(master_NE_sim) && master_NE_sim.shandler && master_NE_sim.shandler.sleeping)
master_NE_sim.shandler.sunlight_update()
if(istype(master_SE_sim) && master_SE_sim.shandler && master_SE_sim.shandler.sleeping)
master_SE_sim.shandler.sunlight_update()
if(istype(master_SW_sim) && master_SW_sim.shandler && master_SW_sim.shandler.sleeping)
master_SW_sim.shandler.sunlight_update()
if(istype(master_NW_sim) && master_NW_sim.shandler && master_NW_sim.shandler.sleeping)
master_NW_sim.shandler.sunlight_update()
//CHOMPEdit End
+33
View File
@@ -5,6 +5,8 @@
///whether we are already in the SSlighting.objects_queue list
var/needs_update = FALSE
var/sunlight_only = FALSE //CHOMPEdit
///the turf that our light is applied to
var/turf/affected_turf
@@ -47,6 +49,7 @@
/datum/lighting_object/proc/update()
if(sunlight_only) return //CHOMPEdit
// To the future coder who sees this and thinks
// "Why didn't he just use a loop?"
// Well my man, it's because the loop performed like shit.
@@ -102,6 +105,7 @@
else
affected_turf.underlays -= current_underlay
current_underlay.icon_state = "gradient"
current_underlay.color = null //CHOMPEdit
current_underlay.color = list(
rr, rg, rb, 00,
gr, gg, gb, 00,
@@ -119,3 +123,32 @@
/datum/lighting_object/proc/addtoturf()
affected_turf.underlays |= current_underlay
//CHOMPEdit Begin
/datum/lighting_object/proc/update_sun()
//Used to have more code here, but it became redundant.
affected_turf.set_luminosity(1)
/datum/lighting_object/proc/set_sunonly(var/onlysun,var/datum/planet_sunlight_handler/pshandler)
if(QDELETED(affected_turf)) //this should never happen but god demanded I be sad
return
switch(sunlight_only)
if(SUNLIGHT_ONLY)
affected_turf.vis_contents -= pshandler.vis_overhead
if(SUNLIGHT_ONLY_SHADE)
affected_turf.vis_contents -= pshandler.vis_shade
if(FALSE)
affected_turf.underlays -= current_underlay
sunlight_only = onlysun
switch(onlysun)
if(SUNLIGHT_ONLY)
affected_turf.vis_contents += pshandler.vis_overhead
if(SUNLIGHT_ONLY_SHADE)
affected_turf.vis_contents += pshandler.vis_shade
if(FALSE)
affected_turf.underlays |= current_underlay
//CHOMPEdit End
+37 -13
View File
@@ -129,6 +129,22 @@
(. * lum_b) - (OLD * applied_lum_b) \
); \
//CHOMPEdit Begin
#define APPLY_CORNER_NEW(C) \
. = LUM_FALLOFF(C, pixel_turf); \
. *= light_power; \
var/OLD = effect_str[C]; \
if (. != 0){ \
LAZYADD(C.affecting, src); \
effect_str[C] = .; \
} \
C.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_b) - (OLD * applied_lum_b) \
); \
//CHOMPEdit End
#define REMOVE_CORNER(C) \
. = -effect_str[C]; \
C.update_lumcount \
@@ -141,8 +157,8 @@
/datum/light_source/proc/remove_lum()
applied = FALSE
for (var/datum/lighting_corner/corner as anything in effect_str)
REMOVE_CORNER(corner)
LAZYREMOVE(corner.affecting, src)
LAZYREMOVE(corner.affecting, src) //CHOMPEdit
REMOVE_CORNER(corner) //CHOMPEdit
effect_str = null
@@ -240,29 +256,37 @@
LAZYINITLIST(effect_str)
if (needs_update == LIGHTING_VIS_UPDATE)
for (var/datum/lighting_corner/corner as anything in new_corners)
APPLY_CORNER(corner)
if (. != 0)
LAZYADD(corner.affecting, src)
effect_str[corner] = .
//CHOMPEdit Begin
APPLY_CORNER_NEW(corner)
//CHOMPEdit End
else
for (var/datum/lighting_corner/corner as anything in new_corners)
APPLY_CORNER(corner)
if (. != 0)
LAZYADD(corner.affecting, src)
effect_str[corner] = .
//CHOMPEdit Begin
APPLY_CORNER_NEW(corner)
//CHOMPEdit End
for (var/datum/lighting_corner/corner as anything in corners - new_corners) // Existing corners
APPLY_CORNER(corner)
//CHOMPEdit Begin
. = LUM_FALLOFF(corner, pixel_turf);
. *= light_power;
var/OLD = effect_str[corner];
if (. != 0)
effect_str[corner] = .
else
LAZYREMOVE(corner.affecting, src)
effect_str -= corner
corner.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_b) - (OLD * applied_lum_b) \
);
//CHOMPEdit End
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)
LAZYREMOVE(corner.affecting, src) //CHOMPEdit
REMOVE_CORNER(corner) //CHOMPEdit
effect_str -= gone_corners
applied_lum_r = lum_r
+28 -5
View File
@@ -96,9 +96,13 @@
///Setter for the byond luminosity var
/turf/proc/set_luminosity(new_luminosity, force)
/*CHOMP Removal Begin
if((is_outdoors() && !force) || outdoors_adjacent)
if(check_for_sun()) //If another system handles our lighting, don't interfere
return
*/ //CHOMP Removal End
if(((is_outdoors() && !force) || outdoors_adjacent) && (z in fake_sunlight_zs)) //Special exception for fakesun lit tiles
return
luminosity = new_luminosity
@@ -141,16 +145,35 @@
/turf/proc/generate_missing_corners()
//CHOMPEdit Begin
var/turf/n = get_step(src,NORTH)
var/turf/s = get_step(src,SOUTH)
var/turf/w = get_step(src,WEST)
var/turf/e = get_step(src,EAST)
if (!lighting_corner_NE)
lighting_corner_NE = new/datum/lighting_corner(src, NORTH|EAST)
if(n && n.lighting_corner_SE)
lighting_corner_NE = n.lighting_corner_SE
else
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(e && e.lighting_corner_SW)
lighting_corner_SE = e.lighting_corner_SW
else
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(s && s.lighting_corner_NW)
lighting_corner_SW = s.lighting_corner_NW
else
lighting_corner_SW = new/datum/lighting_corner(src, SOUTH|WEST)
if (!lighting_corner_NW)
lighting_corner_NW = new/datum/lighting_corner(src, NORTH|WEST)
if(w && w.lighting_corner_NE)
lighting_corner_NW = s.lighting_corner_NE
else
lighting_corner_NW = new/datum/lighting_corner(src, NORTH|WEST)
//CHOMPEdit End
lighting_corners_initialised = TRUE
@@ -0,0 +1,95 @@
/datum/planet_sunlight_handler
var/redint = 0
var/greenint = 0
var/blueint = 0
var/red = 0.0
var/green = 0.0
var/blue = 0.0
var/redshadeint = 0
var/greenshadeint = 0
var/blueshadeint = 0
var/redshade = 0.0
var/greenshade = 0.0
var/blueshade = 0.0
var/cache_r = 0.0
var/cache_g = 0.0
var/cache_b = 0.0
var/cache_r_shade = 0.0
var/cache_g_shade = 0.0
var/cache_b_shade = 0.0
var/maxlum = 0.0
var/maxlumshade = 0.0
var/datum/sun_holder/sun
var/atom/movable/sun_vis_simple/vis_overhead
var/atom/movable/sun_vis_simple/vis_shade
/datum/planet_sunlight_handler/New(var/datum/planet/planet)
. = ..()
sun = planet.sun_holder
vis_overhead = new(null)
vis_shade = new(null)
/datum/planet_sunlight_handler/proc/update_sun()
var/brightness = sun.our_brightness * SSlighting.sun_mult
var/list/color = hex2rgb(sun.our_color)
red = brightness * (color[1] / 255.0)
green = brightness * (color[2] / 255.0)
blue = brightness * (color[3] / 255.0)
redshade = 0.6 * red
greenshade = 0.6 * green
blueshade = 0.6 * blue
redint = round(red * 255)
greenint = round(green * 255)
blueint = round(blue * 255)
redshadeint = round(redshade * 255)
greenshadeint = round(greenshade * 255)
blueshadeint = round(blueshade * 255)
vis_overhead.color = rgb(redint,greenint,blueint)
vis_shade.color = rgb(redshadeint,greenshadeint,blueshadeint)
var/largest_color_luminosity = max(red, green, blue) // Scale it so one of them is the strongest lum, if it is above 1.
maxlum = largest_color_luminosity
. = 1 // factor
if (largest_color_luminosity > 1)
. = 1 / largest_color_luminosity
#if LIGHTING_SOFT_THRESHOLD != 0
else if (largest_color_luminosity < LIGHTING_SOFT_THRESHOLD)
. = 0 // 0 means soft lighting.
cache_r = round(red * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_g = round(green * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_b = round(blue * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
#else
cache_r = round(red * ., LIGHTING_ROUND_VALUE)
cache_g = round(green * ., LIGHTING_ROUND_VALUE)
cache_b = round(blue * ., LIGHTING_ROUND_VALUE)
#endif
largest_color_luminosity = max(redshade, greenshade, blueshade) // Scale it so one of them is the strongest lum, if it is above 1.
maxlumshade = largest_color_luminosity
. = 1 // factor
if (largest_color_luminosity > 1)
. = 1 / largest_color_luminosity
#if LIGHTING_SOFT_THRESHOLD != 0
else if (largest_color_luminosity < LIGHTING_SOFT_THRESHOLD)
. = 0 // 0 means soft lighting.
cache_r_shade = round(redshade * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_g_shade = round(greenshade * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_b_shade = round(blueshade * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
#else
cache_r_shade = round(redshade * ., LIGHTING_ROUND_VALUE)
cache_g_shade = round(greenshade * ., LIGHTING_ROUND_VALUE)
cache_b_shade = round(blueshade * ., LIGHTING_ROUND_VALUE)
#endif
/atom/movable/sun_vis_simple
icon = 'icons/effects/effects.dmi'
icon_state = "white"
plane = PLANE_LIGHTING
mouse_opacity = 0
alpha = 255
color = "#FFFFFF"
@@ -0,0 +1,302 @@
/turf/New(loc, ..., is_turfchange=FALSE)
. = ..(args)
/turf/simulated
var/datum/sunlight_handler/shandler
var/shandler_noinit = FALSE
/turf/simulated/New(loc, ..., is_turfchange=FALSE) //This is so fucking awful have mercy on my soul for writing this
if(is_turfchange)
shandler_noinit = TRUE
. = ..(args)
/turf/simulated/Initialize(mapload)
. = ..(args)
if(mapload)
return INITIALIZE_HINT_LATELOAD
/turf/simulated/LateInitialize()
if((SSplanets && SSplanets.z_to_planet.len >= z && SSplanets.z_to_planet[z]) && has_dynamic_lighting()) //ONLY FOR PLANET TILES IGNORE FAKESUN TILES
if(is_outdoors())
var/turf/T = GetAbove(src)
if(T && !istype(T,/turf/simulated/open))
make_indoors()
if(!shandler_noinit)
shandler = new(src)
shandler.manualInit()
/datum/sunlight_handler
var/datum/sun_holder/sun
var/turf/simulated/holder
var/datum/lighting_object/only_sun_object
var/effect_str_r = 0
var/effect_str_g = 0
var/effect_str_b = 0
var/list/datum/lighting_corner/affected = list()
var/list/datum/lighting_corner/only_sun = list()
var/sunlight = FALSE
var/inherited = FALSE
var/datum/planet_sunlight_handler/pshandler
var/sleeping = FALSE
/datum/sunlight_handler/New(var/parent)
. = ..()
holder = parent
//Moved initialization here to make sure that it doesn't happen too early when replacing turfs.
/datum/sunlight_handler/proc/manualInit()
if(!holder.lighting_corners_initialised)
holder.generate_missing_corners()
var/corners = list(holder.lighting_corner_NE,holder.lighting_corner_NW,holder.lighting_corner_SE,holder.lighting_corner_SW)
for(var/datum/lighting_corner/corner in corners)
if(corner.sunlight == SUNLIGHT_NONE)
corner.sunlight = SUNLIGHT_POSSIBLE
if(SSplanets && SSplanets.z_to_planet.len >= holder.z && SSplanets.z_to_planet[holder.z])
var/datum/planet/planet = SSplanets.z_to_planet[holder.z]
pshandler = SSlighting.get_pshandler(planet)
sun = planet.sun_holder
sunlight_check()
/datum/sunlight_handler/proc/holder_change()
sunlight_update()
for(var/dir in (cardinal + cornerdirs))
var/turf/simulated/T = get_step(holder, dir)
if(istype(T) && T.shandler)
T.shandler.sunlight_update()
sunlight_update()
//Might seem silly and unoptimized to call update twice, but this is not called frequently and it makes things easier.
//Logical flow goes:
//Update 1: Disowns the lighting corner
//Update surrounding turfs: Allows for corner to be claimed by other sunlight handler
//Update 2: Accounts for changes made by surrounding turfs
/datum/sunlight_handler/proc/turf_update(var/old_density, var/turf/new_turf, var/above)
if(above)
sunlight_check()
sunlight_update()
return
if(new_turf.density && !old_density && sunlight) //This has the potential to cut off our sunlight
sunlight_check()
sunlight_update()
else if (!new_turf.density && old_density && !sunlight) //This has the potential to introduce sunlight
sunlight_check()
sunlight_update()
/datum/sunlight_handler/proc/sunlight_check()
set_sleeping(FALSE) //We set sleeping to false just incase. If the conditions are correct, we'll end up going back to sleeping soon enough anyways.
var/cur_sunlight = sunlight
if(holder.is_outdoors())
sunlight = SUNLIGHT_OVERHEAD
if(holder.density)
sunlight = FALSE
if(holder.check_for_sun() && !holder.is_outdoors() && !holder.density)
var/outside_near = FALSE
outer_loop:
for(var/dir in cardinal)
var/steps = 1
var/turf/cur_turf = get_step(holder,dir)
while(cur_turf && !cur_turf.density && steps < (SUNLIGHT_RADIUS + 1))
if(cur_turf.is_outdoors())
outside_near = TRUE
break outer_loop
steps += 1
cur_turf = get_step(cur_turf,dir)
if(!outside_near) //If cardinal directions fail, then check diagonals.
var/radius = ONE_OVER_SQRT_2 * SUNLIGHT_RADIUS + 1
outer_loop:
for(var/dir in cornerdirs)
var/steps = 1
var/turf/cur_turf = get_step(holder,dir)
var/opp_dir = turn(dir,180)
var/north_south = opp_dir & (NORTH|SOUTH)
var/east_west = opp_dir & (EAST|WEST)
while(cur_turf && !cur_turf.density && steps < radius)
var/turf/vert_behind = get_step(cur_turf,north_south)
var/turf/hori_behind = get_step(cur_turf,east_west)
if(vert_behind.density && hori_behind.density) //Prevent light from passing infinitesimally small gaps
break outer_loop
if(cur_turf.is_outdoors())
outside_near = TRUE
break outer_loop
steps += 1
cur_turf = get_step(cur_turf,dir)
if(outside_near)
sunlight = TRUE
else if(sunlight)
sunlight = FALSE
if(cur_sunlight != sunlight)
sunlight_update()
if(!sunlight)
SSlighting.sunlight_queue -= src
else
SSlighting.sunlight_queue += src
/datum/sunlight_handler/proc/sunlight_update()
var/list/corners = list(holder.lighting_corner_NE,holder.lighting_corner_NW,holder.lighting_corner_SE,holder.lighting_corner_SW)
var/list/new_corners = list()
var/list/removed_corners = list()
var/sunlightonly_corners = 0
var/sunlightonly_shade_corners = 0
var/sleepable_corners = 0
for(var/datum/lighting_corner/corner in corners)
switch(corner.sunlight)
if(SUNLIGHT_NONE)
if(sunlight)
corner.sunlight = SUNLIGHT_CURRENT
new_corners += corner
else
corner.sunlight = SUNLIGHT_POSSIBLE
if(SUNLIGHT_POSSIBLE)
if(sunlight)
corner.sunlight = SUNLIGHT_CURRENT
new_corners += corner
if(SUNLIGHT_CURRENT)
if(!sunlight && (corner in affected))
affected -= corner
removed_corners += corner
corner.sunlight = SUNLIGHT_POSSIBLE
if(SUNLIGHT_ONLY)
sunlightonly_corners++
if(!(sunlight == SUNLIGHT_OVERHEAD) && (corner in only_sun))
only_sun -= corner
sunlightonly_corners--
if(sunlight)
new_corners += corner
corner.sunlight = SUNLIGHT_CURRENT
continue
corner.lum_r = 0
corner.lum_g = 0
corner.lum_b = 0
continue
sleepable_corners += corner.all_onlysun()
if(SUNLIGHT_ONLY_SHADE)
sunlightonly_shade_corners++
if(!(sunlight == TRUE) && (corner in only_sun))
only_sun -= corner
sunlightonly_shade_corners--
if(sunlight)
new_corners += corner
corner.sunlight = SUNLIGHT_CURRENT
continue
corner.lum_r = 0
corner.lum_g = 0
corner.lum_b = 0
continue
sleepable_corners += corner.all_onlysun()
if(!sun)
if(SSplanets && SSplanets.z_to_planet.len >= holder.z && SSplanets.z_to_planet[holder.z])
var/datum/planet/planet = SSplanets.z_to_planet[holder.z]
sun = planet.sun_holder
pshandler = SSlighting.get_pshandler(planet)
else
return
var/sunonly_val = (sunlight == SUNLIGHT_OVERHEAD) ? SUNLIGHT_ONLY : SUNLIGHT_ONLY_SHADE
if(sunlight)
for(var/datum/lighting_corner/corner in affected)
if(!LAZYLEN(corner.affecting))
affected -= corner
removed_corners += corner
only_sun += corner
corner.sunlight = sunonly_val
for(var/datum/lighting_corner/corner in new_corners)
if(!LAZYLEN(corner.affecting))
new_corners -= corner
only_sun += corner
corner.sunlight = sunonly_val
if((sunlightonly_corners == 4 || sunlightonly_shade_corners == 4) && !only_sun_object)
var/datum/lighting_object/holder_object = holder.lighting_object
if(holder_object && !holder_object.sunlight_only)
only_sun_object = holder_object
only_sun_object.set_sunonly(sunonly_val, pshandler)
if(sunlightonly_corners < 4 && sunlightonly_shade_corners < 4 && only_sun_object)
only_sun_object.set_sunonly(FALSE, pshandler)
only_sun_object = null
if(only_sun_object)
only_sun_object.update_sun()
for(var/datum/lighting_corner/corner in only_sun)
corner.update_sun(pshandler)
if(sleepable_corners == 4)
set_sleeping(TRUE)
else
set_sleeping(FALSE)
if(!affected.len && !new_corners.len && !removed_corners.len)
return //Nothing to do, avoid wasting time.
var/sunlight_mult = 0
switch(sunlight)
if(TRUE)
sunlight_mult = 0.6
if(SUNLIGHT_OVERHEAD)
sunlight_mult = 1.0
var/brightness = sun.our_brightness * sunlight_mult * SSlighting.sun_mult
var/list/color = hex2rgb(sun.our_color)
var/red = brightness * (color[1] / 255.0)
var/green = brightness * (color[2] / 255.0)
var/blue = brightness * (color[3] / 255.0)
var/delta_r = red - effect_str_r
var/delta_g = green - effect_str_g
var/delta_b = blue - effect_str_b
for(var/datum/lighting_corner/corner in affected)
corner.update_lumcount(delta_r,delta_g,delta_b,from_sholder=TRUE)
for(var/datum/lighting_corner/corner in new_corners)
corner.update_lumcount(red,green,blue,from_sholder=TRUE)
affected += corner
for(var/datum/lighting_corner/corner in removed_corners)
corner.update_lumcount(-effect_str_r,-effect_str_g,-effect_str_b,from_sholder=TRUE)
if(!affected.len)
effect_str_r = 0
effect_str_g = 0
effect_str_b = 0
return
effect_str_r = red
effect_str_g = green
effect_str_b = blue
/datum/sunlight_handler/proc/corner_sunlight_change(var/datum/lighting_corner/sender)
if(only_sun_object)
only_sun_object.set_sunonly(FALSE, pshandler)
only_sun_object = null
set_sleeping(FALSE)
wake_sleepers()
if(!(sender in only_sun))
return
sender.sunlight = SUNLIGHT_CURRENT
sender.update_lumcount(effect_str_r,effect_str_g,effect_str_b,from_sholder=TRUE)
only_sun -= sender
affected += sender
/datum/sunlight_handler/proc/set_sleeping(var/val)
if(sleeping == val)
return
sleeping = val
if(val)
SSlighting.sunlight_queue -= src
else
SSlighting.sunlight_queue |= src //Just in case somehow gets set to false twice use |=
/datum/sunlight_handler/proc/wake_sleepers(var/val)
var/list/corners = list(holder.lighting_corner_NE,holder.lighting_corner_NW,holder.lighting_corner_SE,holder.lighting_corner_SW)
for(var/datum/lighting_corner/corner in corners)
corner.wake_sleepers()