mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
Makes lighting objects objects again (#95332)
## About The Pull Request Continuation of https://github.com/tgstation/tgstation/pull/78857 FOR TOOO LONG WE HAVE SUFF- Ok yeah so like, we made them overlays to save on maptick, but with threaded maptick that is potentially not an issue anymore. I'm opening this pr so I can tm it and see. If it works, it'll save about 50% of lighting object update costs, which is pretty damn good. I'm also removing the fullbright light icon state, since it is barely ever used (it was added as a clientside op, but we don't hit fullbright very much at all so it does nothing but eat my cpu time) Also also changing how SSlighting does its resolution. Rather then waiting for all sources to process, then working on corners and objects, instead we will do all the sources we had at the start, then all the sources after, and so on. The goal is to avoid churn causing the system to constantly choke. it is better to potentially double operate then it is for things to feel horrifically slow. ## Why It's Good For The Game Faster. Also you won't be able to see lights through walls anymore, so mesons will be less dumb. Can maybe bump their nightvision a bit idk we'll see. ## Current Issues to be found ## Changelog 🆑 Absolucy, LemonInTheDark fix: You can no longer see lights through walls when using mesons or when ventcrawling. /🆑 --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
This commit is contained in:
@@ -141,7 +141,7 @@
|
||||
return
|
||||
#endif
|
||||
|
||||
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
|
||||
@@ -163,10 +163,6 @@
|
||||
|
||||
self_destruct_if_idle()
|
||||
|
||||
|
||||
/datum/lighting_corner/dummy/New()
|
||||
return
|
||||
|
||||
/datum/lighting_corner/Destroy(force)
|
||||
if (!force)
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
@@ -1,32 +1,50 @@
|
||||
/datum/lighting_object
|
||||
///the underlay we are currently applying to our turf to apply light
|
||||
var/mutable_appearance/current_underlay
|
||||
|
||||
/atom/movable/lighting_object
|
||||
name = ""
|
||||
anchored = TRUE
|
||||
plane = LIGHTING_PLANE
|
||||
icon = LIGHTING_ICON
|
||||
icon_state = null
|
||||
color = null //we manually set color in init instead
|
||||
appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
move_resist = INFINITY
|
||||
///whether we are already in the SSlighting.objects_queue list
|
||||
var/needs_update = FALSE
|
||||
|
||||
///the turf that our light is applied to
|
||||
var/turf/affected_turf
|
||||
|
||||
// Global list of lighting underlays, indexed by z level
|
||||
GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)
|
||||
|
||||
/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
|
||||
/atom/movable/lighting_object/Initialize(mapload, turf/affected_turf)
|
||||
if(!isnull(loc))
|
||||
if(isturf(loc))
|
||||
affected_turf = loc
|
||||
moveToNullspace()
|
||||
stack_trace("a lighting object was improperly initialized - they should have a null loc, with the affected turf being the second argument")
|
||||
else
|
||||
qdel(src, force = TRUE)
|
||||
CRASH("a lighting object tried to be spawned for a non-turf!")
|
||||
if(!isturf(affected_turf))
|
||||
qdel(src, force = TRUE)
|
||||
CRASH("a lighting object was assigned to [affected_turf], a non turf!")
|
||||
|
||||
. = ..()
|
||||
|
||||
current_underlay = new(GLOB.default_lighting_underlays_by_z[source.z])
|
||||
verbs.Cut()
|
||||
|
||||
affected_turf = source
|
||||
src.affected_turf = affected_turf
|
||||
layer = affected_turf.z * 0.01
|
||||
if(SSmapping.max_plane_offset)
|
||||
// generates the offset lighting plane to use. NOTE: this assumes the turf lighting
|
||||
// plane is ALWAYS offsettable which is technically dependent on a plane master var.
|
||||
// checking for that is slower and this is hot enough that this is a worthwhile risk to take
|
||||
plane = LIGHTING_PLANE - (PLANE_RANGE * GET_Z_PLANE_OFFSET(affected_turf.z))
|
||||
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.vis_contents += src
|
||||
// Default to fullbright, so things can "see" if they use view() before we update
|
||||
affected_turf.luminosity = 1
|
||||
|
||||
@@ -38,18 +56,20 @@ 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.vis_contents -= src
|
||||
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()
|
||||
var/turf/affected_turf = src.affected_turf
|
||||
|
||||
// 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.
|
||||
@@ -60,8 +80,6 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)
|
||||
|
||||
var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new
|
||||
|
||||
var/turf/affected_turf = src.affected_turf
|
||||
|
||||
#ifdef VISUALIZE_LIGHT_UPDATES
|
||||
affected_turf.add_atom_colour(COLOR_BLUE_LIGHT, ADMIN_COLOUR_PRIORITY)
|
||||
animate(affected_turf, 10, color = null)
|
||||
@@ -84,20 +102,12 @@ 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
|
||||
current_underlay.icon_state = "lighting_transparent"
|
||||
current_underlay.color = null
|
||||
else if(!set_luminosity)
|
||||
current_underlay.icon_state = "lighting_dark"
|
||||
current_underlay.color = null
|
||||
if(!set_luminosity)
|
||||
icon_state = "lighting_dark"
|
||||
color = null
|
||||
else
|
||||
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,
|
||||
@@ -105,7 +115,34 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z)
|
||||
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
|
||||
luminosity = set_luminosity
|
||||
|
||||
// Variety of overrides so the overlays don't get affected by weird things.
|
||||
|
||||
/atom/movable/lighting_object/ex_act(severity)
|
||||
return FALSE
|
||||
|
||||
/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/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents = TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return
|
||||
|
||||
/atom/movable/lighting_object/wash(clean_types)
|
||||
SHOULD_CALL_PARENT(FALSE) // lighting objects are dirty, confirmed
|
||||
return
|
||||
|
||||
// Override here to prevent things accidentally moving around overlays.
|
||||
/atom/movable/lighting_object/forceMove(atom/destination, no_tp = FALSE, harderforce = FALSE)
|
||||
if(harderforce)
|
||||
return ..()
|
||||
|
||||
/atom/movable/lighting_object/ref_search_details()
|
||||
return "[text_ref(src)] (turf: [affected_turf ? "[affected_turf.type] @ [AREACOORD(affected_turf)]" : "null"] needs_update: [needs_update ? "true" : "false"])"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
if (lighting_object)
|
||||
qdel(lighting_object, force=TRUE) //Shitty fix for lighting objects persisting after death
|
||||
|
||||
new /datum/lighting_object(src)
|
||||
new /atom/movable/lighting_object(null, src)
|
||||
|
||||
// Used to get a scaled lumcount.
|
||||
/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
|
||||
|
||||
Reference in New Issue
Block a user