Datum lighting (#15931)

* Turns lighting objects into a datum, makes all lighting be performed with an underlay. big maptick fix very good! (#58991)

credit to zewaka for the idea of using underlays

turns the lighting object movables that were unnecessary and increased maptick into a datum which then applies and removes an underlay in update(). also applies a lot of general lighting clean ups (mostly using as anything in loops and fixing single letter var names).

multiz is a little different by necessity, now only the bottom turf's lighting matters in the brightness of the top turf unlike master where the bottom turf's lighting object is hidden from the vis_contents of the top turf. there are still some kinks to iron out here though, since currently objects suspended in openspace (like tram platforms) look bad and glass floors look bad too

only thing i have left to do is make multiz work (well)

UPDATE: multiz now appears the same as far as i can tell, its possible there are other situations in which its different but datum mats work and it automatically updates if the turf below changes. now i just need to make the system less finnicky if at all possible (and possibly merge managed_turf_vis_content with managed_overlays maybe?)

new update: its basically equivalent to normal multiz as far as i can tell (visually at least, in the circumstances ive tested so far)

NEW NEW UPDATE: turfs no longer have the VIS_HIDE vis_flag and multiz works without stacking the lighting from the floor below! so this shouldnt have any overt drawbacks to master anymore

1 needless movable per tile is terrible for maptick. this is probably a larger improvement than my emissive blocker change in terms of maptick. im guessing we'd get around 0.6 average maptick per player after this where currently we get 0.85 or so

Edit: according to lemon, sybil reached 0.71 maptick per person when tm'd with this

if this is a big enough improvement i might finally be able to get rid of the Gone discord avatar

* Revert "Turns lighting objects into a datum, makes all lighting be performed with an underlay. big maptick fix very good! (#58991)"

This reverts commit ffbbeb64f4.

* port from another codebase

Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
This commit is contained in:
Redmoogle
2022-09-30 13:54:14 -04:00
committed by GitHub
parent d1f5234b69
commit a91ef5c4bf
13 changed files with 67 additions and 103 deletions

View File

@@ -8,7 +8,6 @@
/mob/living/silicon/ai,
/obj/effect,
/obj/docking_port,
/atom/movable/lighting_object,
/obj/item/projectile,
))
var/list/processing_list = list(location)

View File

@@ -26,6 +26,7 @@
/obj/screen/plane_master/openspace/backdrop(mob/mymob)
filters = list()
filters += filter(type="alpha", render_source = LIGHTING_RENDER_TARGET, flags = MASK_INVERSE)
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -10)
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -15)
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -20)
@@ -148,4 +149,4 @@
/obj/screen/plane_master/runechat/backdrop(mob/mymob)
filters = list()
if(istype(mymob) && mymob.client?.prefs?.ambientocclusion)
filters += AMBIENT_OCCLUSION
filters += AMBIENT_OCCLUSION

View File

@@ -71,7 +71,7 @@ SUBSYSTEM_DEF(lighting)
MC_SPLIT_TICK
for (i in 1 to GLOB.lighting_update_objects.len)
var/atom/movable/lighting_object/O = GLOB.lighting_update_objects[i]
var/datum/lighting_object/O = GLOB.lighting_update_objects[i]
if (QDELETED(O))
continue
@@ -88,4 +88,4 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/Recover()
initialized = SSlighting.initialized
..()
..()

View File

@@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, flags)
// Remove all atoms except observers, landmarks, docking ports
var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object))
var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark, /obj/docking_port))
var/list/allowed_contents = typecache_filter_list_reverse(GetAllContentsIgnoring(ignore_typecache), ignored_atoms)
allowed_contents -= src
for(var/i in 1 to allowed_contents.len)
@@ -24,10 +24,11 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
var/obj/O
if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay
O = new()
O.underlays.Add(T)
O.underlays += T
T.ChangeTurf(type)
if(underlays.len)
T.underlays = O.underlays
T.underlays.Cut()
T.underlays += O.underlays
if(T.icon_state != icon_state)
T.icon_state = icon_state
if(T.icon != icon)
@@ -129,6 +130,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
lighting_build_overlay()
else
lighting_clear_overlay()
else if(lighting_object && !lighting_object.needs_update)
lighting_object.update()
for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()

View File

@@ -27,7 +27,7 @@
//Variables declared to change how items in the launch bay are picked and launched. (Almost) all of these are changed in the ui_act proc
//Some effect groups are choices, while other are booleans. This is because some effects can stack, while others dont (ex: you can stack explosion and quiet, but you cant stack ordered launch and random launch)
/datum/centcom_podlauncher
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object, /obj/effect/particle_effect/sparks, /obj/effect/DPtarget, /obj/effect/hallucination/simple/supplypod_selector, /obj/effect/hallucination/simple/dropoff_location))
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /obj/effect/particle_effect/sparks, /obj/effect/DPtarget, /obj/effect/hallucination/simple/supplypod_selector, /obj/effect/hallucination/simple/dropoff_location))
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
var/client/holder //client of whoever is using this datum
var/area/centcom/supplypod/loading/bay //What bay we're using to launch shit from.

View File

@@ -1,65 +1,48 @@
/atom/movable/lighting_object
name = ""
anchored = TRUE
icon = LIGHTING_ICON
icon_state = "transparent"
color = null //we manually set color in init instead
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
/datum/lighting_object
///the underlay we are currently applying to our turf to apply light
var/mutable_appearance/current_underlay
///whether we are already in the SSlighting.objects_queue list
var/needs_update = FALSE
var/turf/myturf
/atom/movable/lighting_object/Initialize(mapload)
///the turf that our light is applied to
var/turf/affected_turf
/datum/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
. = ..()
verbs.Cut()
//We avoid setting this in the base as if we do then the parent atom handling will add_atom_color it and that
//is totally unsuitable for this object, as we are always changing it's colour manually
color = LIGHTING_BASE_MATRIX
myturf = loc
if (myturf.lighting_object)
qdel(myturf.lighting_object, force = TRUE)
myturf.lighting_object = src
myturf.luminosity = 0
current_underlay = mutable_appearance(LIGHTING_ICON, "transparent", source.z, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM)
for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
affected_turf = source
if (affected_turf.lighting_object)
qdel(affected_turf.lighting_object, force = TRUE)
stack_trace("a lighting object was assigned to a turf that already had a lighting object!")
affected_turf.lighting_object = src
affected_turf.luminosity = 0
for(var/turf/open/space/space_tile in RANGE_TURFS(1, affected_turf))
space_tile.update_starlight()
needs_update = TRUE
GLOB.lighting_update_objects += src
/atom/movable/lighting_object/Destroy(var/force)
if (force)
GLOB.lighting_update_objects -= src
if (loc != myturf)
var/turf/oldturf = get_turf(myturf)
var/turf/newturf = get_turf(loc)
stack_trace("A lighting object was qdeleted with a different loc then it is suppose to have ([COORD(oldturf)] -> [COORD(newturf)])")
if (isturf(myturf))
myturf.lighting_object = null
myturf.luminosity = 1
myturf = null
return ..()
else
/datum/lighting_object/Destroy(force)
if (!force)
return QDEL_HINT_LETMELIVE
GLOB.lighting_update_objects -= src
if (isturf(affected_turf))
affected_turf.lighting_object = null
affected_turf.luminosity = 1
affected_turf.underlays -= current_underlay
affected_turf = null
return ..()
/atom/movable/lighting_object/proc/update()
if (loc != myturf)
if (loc)
var/turf/oldturf = get_turf(myturf)
var/turf/newturf = get_turf(loc)
warning("A lighting object realised it's loc had changed in update() ([myturf]\[[myturf ? myturf.type : "null"]]([COORD(oldturf)]) -> [loc]\[[ loc ? loc.type : "null"]]([COORD(newturf)]))!")
qdel(src, TRUE)
return
/datum/lighting_object/proc/update()
// To the future coder who sees this and thinks
// "Why didn't he just use a loop?"
@@ -69,10 +52,9 @@
// Oh it's also shorter line wise.
// Including with these comments.
// 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/list/corners = affected_turf.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
@@ -110,15 +92,20 @@
#endif
if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8))
//anything that passes the first case is very likely to pass the second, and addition is a little faster in this case
icon_state = "transparent"
color = null
//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"
current_underlay.color = null
affected_turf.underlays += current_underlay
else if(!set_luminosity)
icon_state = "dark"
color = null
affected_turf.underlays -= current_underlay
current_underlay.icon_state = "dark"
current_underlay.color = null
affected_turf.underlays += current_underlay
else
icon_state = null
color = list(
affected_turf.underlays -= current_underlay
current_underlay.icon_state = null
current_underlay.color = list(
rr, rg, rb, 00,
gr, gg, gb, 00,
br, bg, bb, 00,
@@ -126,29 +113,6 @@
00, 00, 00, 01
)
luminosity = set_luminosity
affected_turf.underlays += current_underlay
// 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()
return
/atom/movable/lighting_object/onTransitZ()
return
/atom/movable/lighting_object/wash(clean_types)
return
// Override here to prevent things accidentally moving around overlays.
/atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
if(harderforce)
. = ..()
affected_turf.luminosity = set_luminosity

View File

@@ -8,6 +8,6 @@
if(!IS_DYNAMIC_LIGHTING(T))
continue
new/atom/movable/lighting_object(T)
new/datum/lighting_object(T)
CHECK_TICK
CHECK_TICK

View File

@@ -5,7 +5,7 @@
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/datum/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.
@@ -41,7 +41,7 @@
if (!lighting_corners_initialised)
generate_missing_corners()
new/atom/movable/lighting_object(src)
new/datum/lighting_object(src)
var/thing
var/datum/lighting_corner/C
@@ -84,7 +84,7 @@
if (!lighting_object)
return FALSE
return !lighting_object.luminosity
return !luminosity
// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
/turf/proc/recalc_atom_opacity()

View File

@@ -190,7 +190,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 || the_target.type == /atom/movable/lighting_object) // bail out on invalids
if(isturf(the_target) || !the_target) // bail out on invalids
return FALSE
if(ismob(the_target)) //Target is in godmode, ignore it.

View File

@@ -51,7 +51,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 || the_target.type == /atom/movable/lighting_object) // bail out on invalids
if(isturf(the_target) || !the_target) // bail out on invalids
return FALSE
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it

View File

@@ -64,7 +64,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) || istype(the_target, /atom/movable/lighting_object))
if(!the_target || isturf(the_target))
return FALSE
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it

View File

@@ -207,7 +207,7 @@
msg = blind_message
else if(T != loc && T != src) //if src is inside something and not a turf.
msg = blind_message
else if(T.lighting_object && T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit()) //if it is too dark.
else if(M.lighting_alpha > LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE && T.is_softly_lit() && !in_range(T,M)) //if it is too dark.
msg = blind_message
if(!msg)
continue

View File

@@ -373,9 +373,6 @@ All ShuttleMove procs go here
/************************************Misc move procs************************************/
/atom/movable/lighting_object/onShuttleMove()
return FALSE
/obj/docking_port/mobile/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(moving_dock == src)