Skip to content

Commit

Permalink
add: Light system rework (ss220-space#5001)
Browse files Browse the repository at this point in the history
* add: Experimental lighting rework

* Additional optimization for less proc calls

* Update code/modules/lighting/lighting_emissive_blocker.dm
  • Loading branch information
Vladisvell authored May 10, 2024
1 parent 86eb5fa commit c849eca
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 33 deletions.
2 changes: 1 addition & 1 deletion code/controllers/subsystem/lighting.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ SUBSYSTEM_DEF(lighting)
queue = objects_queue
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/lighting_object/O = queue[i]
var/atom/movable/lighting_object/O = queue[i]

if(QDELETED(O))
continue
Expand Down
2 changes: 1 addition & 1 deletion code/modules/awaymissions/zvis.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
/obj/effect/portal_sensor/proc/check_light()
var/turf/T = loc
if(istype(T) && T.lighting_object && !T.lighting_object.needs_update)
var/datum/lighting_object/O = T.lighting_object
var/atom/movable/lighting_object/O = T.lighting_object
var/hash = 0
for(var/lighting_corner in O)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/lighting/lighting_corner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@

src.largest_color_luminosity = round(largest_color_luminosity, LIGHTING_ROUND_VALUE)

var/datum/lighting_object/lighting_object = master_NE?.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
Expand Down
12 changes: 12 additions & 0 deletions code/modules/lighting/lighting_emissive_blocker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,15 @@
if(harderforce)
return ..()

/atom/movable/emissive_blocker/Crossed(atom/movable/AM, oldloc)
return

/atom/movable/emissive_blocker/Uncrossed(atom/movable/AM)
return

/atom/movable/emissive_blocker/Bump(atom/A, yes)
return

/atom/movable/emissive_blocker/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, dodgeable)
return

84 changes: 60 additions & 24 deletions code/modules/lighting/lighting_object.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
/datum/lighting_object
/atom/movable/lighting_object
name = ""
anchored = TRUE
icon = LIGHTING_ICON
icon_state = "transparent"
color = null
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
simulated = FALSE

var/turf/myturf

///the underlay we are currently applying to our turf to apply light
var/mutable_appearance/current_underlay
//var/mutable_appearance/current_underlay

///whether we are already in the SSlighting.objects_queue list
var/needs_update = FALSE
Expand All @@ -11,15 +24,13 @@
// Global list of lighting underlays, indexed by z level
GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)

/datum/lighting_object/New(turf/source)
/atom/movable/lighting_object/New(turf/source)
if(!isturf(source))
qdel(src, force=TRUE)
stack_trace("a lighting object was assigned to [source], a non turf! ")
return
. = ..()

current_underlay = new(GLOB.default_lighting_underlays_by_z[source.z])

affected_turf = source
if (affected_turf.lighting_object)
qdel(affected_turf.lighting_object, force = TRUE)
Expand All @@ -37,18 +48,17 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)
needs_update = TRUE
SSlighting.objects_queue += src

/datum/lighting_object/Destroy(force)
/atom/movable/lighting_object/Destroy(force)
if (!force)
return QDEL_HINT_LETMELIVE
SSlighting.objects_queue -= src
if (isturf(affected_turf))
affected_turf.lighting_object = null
affected_turf.luminosity = 1
affected_turf.underlays -= current_underlay
affected_turf = null
return ..()

/datum/lighting_object/proc/update()
/atom/movable/lighting_object/proc/update()
// 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.
Expand Down Expand Up @@ -76,33 +86,59 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)
var/set_luminosity = max > 1e-6
#endif

var/mutable_appearance/current_underlay = src.current_underlay
affected_turf.underlays -= current_underlay
if(red_corner.cache_r & green_corner.cache_r & blue_corner.cache_r & alpha_corner.cache_r && \
(red_corner.cache_g + green_corner.cache_g + blue_corner.cache_g + alpha_corner.cache_g + \
red_corner.cache_b + green_corner.cache_b + blue_corner.cache_b + alpha_corner.cache_b == 8))
//anything that passes the first case is very likely to pass the second, and addition is a little faster in this case
affected_turf.underlays -= current_underlay
current_underlay.icon_state = "transparent_lighting_object"
current_underlay.color = null
affected_turf.underlays += current_underlay
icon_state = "transparent_lighting_object"
color = null
else if(!set_luminosity)
affected_turf.underlays -= current_underlay
current_underlay.icon_state = "dark_lighting_object"
current_underlay.color = null
affected_turf.underlays += current_underlay
icon_state = "dark_lighting_object"
color = null
else
affected_turf.underlays -= current_underlay
current_underlay.icon_state = null
current_underlay.color = list(
icon_state = null
color = list(
red_corner.cache_r, red_corner.cache_g, red_corner.cache_b, 00,
green_corner.cache_r, green_corner.cache_g, green_corner.cache_b, 00,
blue_corner.cache_r, blue_corner.cache_g, blue_corner.cache_b, 00,
alpha_corner.cache_r, alpha_corner.cache_g, alpha_corner.cache_b, 00,
00, 00, 00, 01
)

// Of note. Most of the cost in this proc is here, I think because color matrix'd underlays DO NOT cache well, which is what adding to underlays does
// We use underlays because objects on each tile would fuck with maptick. if that ever changes, use an object for this instead
affected_turf.underlays += current_underlay
affected_turf.luminosity = set_luminosity


// Variety of overrides so the overlays don't get affected by weird things.

/atom/movable/lighting_object/ex_act(severity)
return 0

/atom/movable/lighting_object/singularity_act()
return

/atom/movable/lighting_object/singularity_pull()
return

/atom/movable/lighting_object/blob_act(obj/structure/blob/B)
return

/atom/movable/lighting_object/onTransitZ()
return

// Override here to prevent things accidentally moving around overlays.
/atom/movable/lighting_object/forceMove(atom/destination, no_tp = FALSE, harderforce = FALSE)
if(harderforce)
. = ..()

/atom/movable/lighting_object/Crossed(atom/movable/AM, oldloc)
return

/atom/movable/lighting_object/Uncrossed(atom/movable/AM)
return

/atom/movable/lighting_object/Bump(atom/A, yes)
return

/atom/movable/lighting_object/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, dodgeable)
return

2 changes: 1 addition & 1 deletion code/modules/lighting/lighting_setup.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
if(!IS_DYNAMIC_LIGHTING(T))
continue

new/datum/lighting_object(T)
new/atom/movable/lighting_object(T)
CHECK_TICK
CHECK_TICK
4 changes: 2 additions & 2 deletions code/modules/lighting/lighting_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

var/tmp/lighting_corners_initialised = FALSE

var/tmp/datum/lighting_object/lighting_object // Our lighting object.
var/tmp/atom/movable/lighting_object/lighting_object // Our lighting object.
///Lighting Corner datums.
var/tmp/datum/lighting_corner/lighting_corner_NE
var/tmp/datum/lighting_corner/lighting_corner_SE
Expand Down Expand Up @@ -32,7 +32,7 @@
if(!IS_DYNAMIC_LIGHTING(A) && !light_sources)
return

new/datum/lighting_object(src)
new/atom/movable/lighting_object(src)

// Used to get a scaled lumcount.
/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/simple_animal/hostile/hostile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@

// Please do not add one-off mob AIs here, but override this function for your mob
/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(isturf(the_target) || !the_target) // bail out on invalids
if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
return FALSE

if(ismob(the_target)) //Target is in godmode, ignore it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
return ..()

/mob/living/simple_animal/hostile/asteroid/gutlunch/CanAttack(atom/the_target) // Gutlunch-specific version of CanAttack to handle stupid stat_exclusive = true crap so we don't have to do it for literally every single simple_animal/hostile except the two that spawn in lavaland
if(isturf(the_target) || !the_target) // bail out on invalids
if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
return FALSE

if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/simple_animal/hostile/mushroom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
..()

/mob/living/simple_animal/hostile/mushroom/CanAttack(atom/the_target) // Mushroom-specific version of CanAttack to handle stupid attack_same = 2 crap so we don't have to do it for literally every single simple_animal/hostile because this shit never gets spawned
if(!the_target || isturf(the_target))
if(!the_target || isturf(the_target) || istype(the_target, /atom/movable/lighting_object))
return FALSE

if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
Expand Down

0 comments on commit c849eca

Please sign in to comment.