Files
Matt Atlas 94d92803b4 Replaces our lighting system with CM's. (#21465)
Depends on #21458.

Ports https://github.com/cmss13-devs/cmss13/pull/4229, with the original
authors as:

- https://github.com/tgstation/TerraGov-Marine-Corps/pull/1964 for the
lighting controller (A-lexa)
- https://github.com/tgstation/TerraGov-Marine-Corps/pull/4747 and
https://github.com/tgstation/TerraGov-Marine-Corps/pull/7263 for the
lighting (TiviPlus)
- https://github.com/tgstation/tgstation/pull/54520 for the dir lighting
component
- https://github.com/tgstation/tgstation/pull/75018 for the out of
bounds fix in lighting
- https://github.com/tgstation/TerraGov-Marine-Corps/pull/6678 for the
emissives (TiviPlus)

The main driving reason behind this is that current lighting consumes
way too much processing power, especially for things like odysseys/away
sites where a billion light sources are processing/moving at once and
the game slows down to a crawl. Hopefully this improves the situation by
a good margin, but we will need some testmerging to confirm that.
<img width="1349" height="1349" alt="image"
src="https://github.com/user-attachments/assets/1059ba2b-c0c5-495a-9c76-2d75d0c42bf2"
/>
<img width="1349" height="1349" alt="image"
src="https://github.com/user-attachments/assets/9704b0f6-4cf6-4dfd-a6cb-5702ad07d677"
/>


- [x] Resolve todos
- [x] Look into open space fuckery (border objects)

---------

Co-authored-by: Matt Atlas <liermattia@gmail.com>
Co-authored-by: JohnWildkins <john.wildkins@gmail.com>
2025-11-04 21:27:42 +00:00

186 lines
4.9 KiB
Plaintext

// The proc you should always use to set the light of this atom.
// Nonesensical value for l_color default, so we can detect if it gets set to null.
#define NONSENSICAL_VALUE -99999
/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE, mask_type = null)
if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
if(l_power != null && l_power != light_power)
light_power = l_power
. = TRUE
if(l_range != null && l_range != light_range)
light_range = l_range
light_on = (light_range>0) ? TRUE : FALSE
. = TRUE
if(l_color != NONSENSICAL_VALUE && l_color != light_color)
light_color = l_color
. = TRUE
if(mask_type != null && mask_type != light_mask_type)
light_mask_type = mask_type
. = TRUE
if(.)
update_light()
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, l_color)
/atom/proc/fade_light(new_colour, time)
light_color = new_colour
if(light?.our_mask)
animate(light.our_mask, color = new_colour, time = time)
/// Will update the light (duh).Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
/atom/proc/update_light()
set waitfor = FALSE
if(QDELETED(src))
return
if(light_system == STATIC_LIGHT)
static_update_light()
return
if((!light_power || !light_range) && light) // We won't emit light anyways, destroy the light source.
QDEL_NULL(light)
return
if(light && light_mask_type && (light_mask_type != light.mask_type))
QDEL_NULL(light)
if(!light) // Update the light or create it if it does not exist.
light = new /datum/dynamic_light_source(src, light_mask_type)
return
light.set_light(light_range, light_power, light_color)
light.update_position()
/**
* Updates the atom's opacity value.
*
* This exists to act as a hook for associated behavior.
* It notifies (potentially) affected light sources so they can update (if needed).
*/
/atom/proc/set_opacity(new_opacity)
if(new_opacity == opacity)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_OPACITY, new_opacity)
. = opacity
opacity = new_opacity
/atom/movable/set_opacity(new_opacity)
. = ..()
if(isnull(.) || !isturf(loc))
return
if(opacity)
AddElement(/datum/element/light_blocking)
else
RemoveElement(/datum/element/light_blocking)
/turf/set_opacity(new_opacity)
. = ..()
if(isnull(.))
return
recalculate_directional_opacity()
/atom/vv_edit_var(var_name, var_value)
switch(var_name)
if("light_range")
if(light_system != MOVABLE_LIGHT)
set_light(l_range = var_value)
else
set_light_range(var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
if("light_power")
if(light_system != MOVABLE_LIGHT)
set_light(l_power = var_value)
else
set_light_power(var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
if("light_color")
if(light_system != MOVABLE_LIGHT)
set_light(l_color = var_value)
else
set_light_color(var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
return ..()
/atom/proc/flash_lighting_fx(
_range = FLASH_LIGHT_RANGE,
_power = FLASH_LIGHT_POWER,
_color = COLOR_WHITE,
_duration = FLASH_LIGHT_DURATION,
_reset_lighting = TRUE,
_flash_times = 1)
new /obj/effect/light_flash(get_turf(src), _range, _power, _color, _duration, _flash_times)
/obj/effect/light_flash/Initialize(mapload, _range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _flash_times = 1)
light_range = _range
light_power = _power
light_color = _color
. = ..()
do_flashes(_flash_times, _duration)
/obj/effect/light_flash/proc/do_flashes(_flash_times, _duration)
set waitfor = FALSE
for(var/i in 1 to _flash_times)
//Something bad happened
if(!(light?.our_mask))
break
light.our_mask.alpha = 255
animate(light.our_mask, time = _duration, easing = SINE_EASING, alpha = 0, flags = ANIMATION_END_NOW)
sleep(_duration) //this is extremely short so it's ok to sleep
qdel(src)
/atom/proc/set_light_range(new_range)
if(new_range == light_range)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_RANGE, new_range)
. = light_range
light_range = new_range
/atom/proc/set_light_power(new_power)
if(new_power == light_power)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_POWER, new_power)
. = light_power
light_power = new_power
/atom/proc/set_light_color(new_color)
if(new_color == light_color)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_COLOR, new_color)
. = light_color
light_color = new_color
/atom/proc/set_light_on(new_value)
if(new_value == light_on)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ON, new_value)
. = light_on
light_on = new_value
/// Setter for the light flags of this atom.
/atom/proc/set_light_flags(new_value)
if(new_value == light_flags)
return
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_FLAGS, new_value)
. = light_flags
light_flags = new_value