Object based lighting system

Uses actual objects on each non-space, dynamically lit turf. Light levels are switched back and forth via animate() and the object's alpha. Supporting colors shouldn't be too hard. Some hacky efficiency improvements means it isn't that much more expensive than current (I think, needs testing). Most of the lighting ss's cost is in checking all the lights and doing big loops, not anything actually in the loops themselves.

Start PDA flashlights on. This was to speed up testing but frankly I think it's a good change in general.

Added a Moved() proc. Called after a successful move.

In the future I hope to move off the luminosity var entirely but that was too slow in testing for me. That's what all that "for(area in sortedAreas) area.luminosity = 1" stuff in the lighting ss is, tests on removing luminosity outright.
This commit is contained in:
MrPerson
2015-03-31 05:09:42 -07:00
parent 005c519b94
commit e4a3abdd70
15 changed files with 189 additions and 153 deletions
+27 -28
View File
@@ -1,15 +1,12 @@
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
@@ -19,11 +16,6 @@ var/datum/subsystem/lighting/SSlighting
/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 ..()
@@ -38,19 +30,26 @@ var/datum/subsystem/lighting/SSlighting
//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)
// for(var/area/A in sortedAreas)
// A.luminosity = 1
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
qdel(lights[i])
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()
thing:redraw_lighting()
changed_turfs.Cut()
// for(var/area/A in sortedAreas)
// A.luminosity = !A.lighting_use_dynamic
//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.
@@ -58,11 +57,15 @@ var/datum/subsystem/lighting/SSlighting
//z-levels with the z_level argument
/datum/subsystem/lighting/Initialize(timeofday, z_level)
// for(var/area/A in sortedAreas)
// A.luminosity = 1
var/i=1
for(var/thing in lights)
if(thing && !thing:check())
++i
continue
qdel(lights[i])
lights.Cut(i, i+1)
var/z_start = 1
@@ -72,12 +75,10 @@ var/datum/subsystem/lighting/SSlighting
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()
var/list/turfs_to_init = block(locate(1, 1, z_start), locate(world.maxx, world.maxy, z_finish))
for(var/T in turfs_to_init)
T:init_lighting()
if(z_level)
//we need to loop through to clear only shifted turfs from the list. or we will cause errors
@@ -90,10 +91,8 @@ var/datum/subsystem/lighting/SSlighting
else
changed_turfs.Cut()
if(config.starlight)
set background = 1
for(var/turf/space/S in world)
S.update_starlight()
// for(var/area/A in sortedAreas)
// A.luminosity = !A.lighting_use_dynamic
..()
@@ -106,18 +105,18 @@ var/datum/subsystem/lighting/SSlighting
if(!istype(SSlighting.lights))
SSlighting.lights = list()
if(istype(SSlighting.lighting_images))
lighting_images = SSlighting.lighting_images
// for(var/area/A in sortedAreas)
// A.luminosity = 1
for(var/datum/light_source/L in SSlighting.lights)
for(var/L in SSlighting.lights)
spawn(-1) //so we don't crash the loop (inefficient)
L.check()
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)
for(var/T in changed_turfs)
if(T:lighting_changed)
spawn(-1)
T.shift_to_subarea()
T:redraw_lighting()
var/msg = "## DEBUG: [time2text(world.timeofday)] [name] subsystem restarted. Reports:\n"
for(var/varname in SSlighting.vars)
@@ -132,5 +131,5 @@ var/datum/subsystem/lighting/SSlighting
msg += "\t [varname] = [varval1] -> [varval2]\n"
world.log << msg
#undef LIGHTING_ICON
#undef LIGHTING_LAYER
// for(var/area/A in sortedAreas)
// A.luminosity = !A.lighting_use_dynamic