mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-10 08:54:15 +00:00
136 lines
4.6 KiB
Plaintext
136 lines
4.6 KiB
Plaintext
var/datum/subsystem/lighting/SSlighting
|
|
|
|
#define MC_AVERAGE(average, current) (0.8*(average) + 0.2*(current))
|
|
#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi'
|
|
#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
|
|
|
|
/datum/subsystem/lighting
|
|
name = "Lighting"
|
|
wait = 5
|
|
priority = 1
|
|
|
|
var/list/lighting_images = list() //replaces lighting_states (use lighting_images.len) ~carn
|
|
var/list/lights = list() //list of all datum/light_source
|
|
var/lights_workload = 0 //stats on the largest number of lights (max lights.len)
|
|
var/list/changed_turfs = list() //list of all turfs which need moving to a new lighting subarea
|
|
var/changed_turfs_workload = 0 //stats on the largest number of turfs changed (max changed_turfs.len)
|
|
|
|
|
|
/datum/subsystem/lighting/New()
|
|
NEW_SS_GLOBAL(SSlighting)
|
|
|
|
//cache lighting images
|
|
if(!lighting_images.len)
|
|
for(var/icon_state in icon_states(LIGHTING_ICON))
|
|
lighting_images += image(LIGHTING_ICON, null, icon_state, LIGHTING_LAYER)
|
|
|
|
return ..()
|
|
|
|
|
|
/datum/subsystem/lighting/stat_entry()
|
|
stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%) L:[round(lights_workload,1)]/T:[round(changed_turfs_workload,1)]")
|
|
|
|
|
|
//Workhorse of lighting. It cycles through each light to see which ones need their effects updating. It updates their
|
|
//effects and then processes every turf in the queue, moving the turfs to the corresponing lighting sub-area.
|
|
//All queue lists prune themselves, which will cause lights with no luminosity to be garbage collected (cheaper and safer
|
|
//than deleting them).
|
|
//By using queues we are ensuring we don't perform more updates than are necessary
|
|
/datum/subsystem/lighting/fire()
|
|
lights_workload = MC_AVERAGE(lights_workload, lights.len)
|
|
var/i=1
|
|
for(var/thing in lights)
|
|
if(thing && !thing:check()) //yes, cry that I'm using the : operator, it's much faster looping like this. And this gets called a lot. Dealwithit.
|
|
++i
|
|
continue
|
|
lights.Cut(i, i+1)
|
|
|
|
changed_turfs_workload = MC_AVERAGE(changed_turfs_workload, changed_turfs.len)
|
|
for(var/thing in changed_turfs)
|
|
if(thing && thing:lighting_changed)
|
|
thing:shift_to_subarea()
|
|
changed_turfs.Cut()
|
|
|
|
|
|
//same as above except it attempts to shift ALL turfs in the world regardless of lighting_changed status
|
|
//Does not loop. Should be run prior to process() being called for the first time.
|
|
//Note: if we get additional z-levels at runtime (e.g. if the gateway thin ever gets finished) we can initialize specific
|
|
//z-levels with the z_level argument
|
|
/datum/subsystem/lighting/Initialize(timeofday, z_level)
|
|
|
|
var/i=1
|
|
for(var/thing in lights)
|
|
if(thing && !thing:check())
|
|
++i
|
|
continue
|
|
lights.Cut(i, i+1)
|
|
|
|
var/z_start = 1
|
|
var/z_finish = world.maxz
|
|
if(1 <= z_level && z_level <= world.maxz)
|
|
z_level = round(z_level)
|
|
z_start = z_level
|
|
z_finish = z_level
|
|
|
|
for(var/z=z_start, z<=z_finish, ++z)
|
|
for(var/x=1, x<=world.maxx, ++x)
|
|
for(var/y=1, y<=world.maxy, ++y)
|
|
var/turf/T = locate(x,y,z)
|
|
if(T)
|
|
T.shift_to_subarea()
|
|
|
|
if(z_level)
|
|
//we need to loop through to clear only shifted turfs from the list. or we will cause errors
|
|
i=1
|
|
for(var/thing in changed_turfs)
|
|
if(thing && thing:z < z_start && z_finish < thing:z)
|
|
++i
|
|
continue
|
|
changed_turfs.Cut(i, i+1)
|
|
else
|
|
changed_turfs.Cut()
|
|
|
|
if(config.starlight)
|
|
set background = 1
|
|
for(var/turf/space/S in world)
|
|
S.update_starlight()
|
|
|
|
..()
|
|
|
|
//Used to strip valid information from an existing instance and transfer it to the replacement. i.e. when a crash occurs
|
|
//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop
|
|
//does not crash
|
|
/datum/subsystem/lighting/Recover()
|
|
if(!istype(SSlighting.changed_turfs))
|
|
SSlighting.changed_turfs = list()
|
|
if(!istype(SSlighting.lights))
|
|
SSlighting.lights = list()
|
|
|
|
if(istype(SSlighting.lighting_images))
|
|
lighting_images = SSlighting.lighting_images
|
|
|
|
for(var/datum/light_source/L in SSlighting.lights)
|
|
spawn(-1) //so we don't crash the loop (inefficient)
|
|
L.check()
|
|
lights += L //If we didn't runtime then this will get transferred over
|
|
|
|
for(var/turf/T in changed_turfs)
|
|
if(T.lighting_changed)
|
|
spawn(-1)
|
|
T.shift_to_subarea()
|
|
|
|
var/msg = "## DEBUG: [time2text(world.timeofday)] [name] subsystem restarted. Reports:\n"
|
|
for(var/varname in SSlighting.vars)
|
|
switch(varname)
|
|
if("tag","bestF","type","parent_type","vars") continue
|
|
else
|
|
var/varval1 = SSlighting.vars[varname]
|
|
var/varval2 = vars[varname]
|
|
if(istype(varval1,/list))
|
|
varval1 = "/list([length(varval1)])"
|
|
varval2 = "/list([length(varval2)])"
|
|
msg += "\t [varname] = [varval1] -> [varval2]\n"
|
|
world.log << msg
|
|
|
|
#undef LIGHTING_ICON
|
|
#undef LIGHTING_LAYER |