mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-24 09:14:17 +00:00
This commit adds a small sanity check to the falloff calculations of lights, to prevent them from dividing by 0. This may cause undiscovered strangeness, but strangeness is better than filling the runtime log. This commit also fixes the supply shuttle, which was not spawning any ordered items. It did this because it had a very basic contents.len check which the lighting overlays triggered. The sanity check to not spawn stuff on top of other stuff is now a for(atom) loop on the turfs, which has snowflake checks for lights and lighting overlays.
169 lines
4.1 KiB
Plaintext
169 lines
4.1 KiB
Plaintext
/datum/light_source
|
|
var/atom/top_atom
|
|
var/atom/source_atom
|
|
|
|
var/turf/source_turf
|
|
var/light_power
|
|
var/light_range
|
|
var/light_color // string, decomposed by parse_light_color()
|
|
|
|
var/lum_r
|
|
var/lum_g
|
|
var/lum_b
|
|
|
|
var/list/effect_r
|
|
var/list/effect_g
|
|
var/list/effect_b
|
|
var/list/effect_turf
|
|
|
|
var/applied
|
|
|
|
var/needs_update
|
|
var/destroyed
|
|
var/force_update
|
|
|
|
/datum/light_source/New(atom/owner, atom/top)
|
|
source_atom = owner
|
|
if(!source_atom.light_sources) source_atom.light_sources = list()
|
|
source_atom.light_sources += src
|
|
top_atom = top
|
|
if(top_atom != source_atom)
|
|
if(!top.light_sources) top.light_sources = list()
|
|
top_atom.light_sources += src
|
|
|
|
source_turf = top_atom
|
|
light_power = source_atom.light_power
|
|
light_range = source_atom.light_range
|
|
light_color = source_atom.light_color
|
|
|
|
parse_light_color()
|
|
|
|
effect_r = list()
|
|
effect_g = list()
|
|
effect_b = list()
|
|
effect_turf = list()
|
|
|
|
update()
|
|
|
|
return ..()
|
|
|
|
/datum/light_source/proc/destroy()
|
|
destroyed = 1
|
|
force_update()
|
|
if(source_atom) source_atom.light_sources -= src
|
|
if(top_atom) top_atom.light_sources -= src
|
|
|
|
/datum/light_source/proc/update(atom/new_top_atom)
|
|
if(new_top_atom && new_top_atom != top_atom)
|
|
if(top_atom != source_atom) top_atom.light_sources -= src
|
|
top_atom = new_top_atom
|
|
if(top_atom != source_atom)
|
|
if(!top_atom.light_sources) top_atom.light_sources = list()
|
|
top_atom.light_sources += src
|
|
lighting_update_lights += src
|
|
needs_update = 1
|
|
|
|
/datum/light_source/proc/force_update()
|
|
needs_update = 1
|
|
force_update = 1
|
|
lighting_update_lights += src
|
|
|
|
/datum/light_source/proc/check()
|
|
if(!source_atom)
|
|
destroy()
|
|
return 1
|
|
|
|
if(!top_atom)
|
|
top_atom = source_atom
|
|
. = 1
|
|
|
|
if(istype(top_atom, /turf))
|
|
if(source_turf != top_atom)
|
|
source_turf = top_atom
|
|
. = 1
|
|
else if(top_atom.loc != source_turf)
|
|
source_turf = top_atom.loc
|
|
. = 1
|
|
|
|
if(source_atom.light_power != light_power)
|
|
light_power = source_atom.light_power
|
|
. = 1
|
|
|
|
if(source_atom.light_range != light_range)
|
|
light_range = source_atom.light_range
|
|
. = 1
|
|
|
|
if(source_atom.light_color != light_color)
|
|
light_color = source_atom.light_color
|
|
parse_light_color()
|
|
. = 1
|
|
|
|
if(light_range && light_power && !applied)
|
|
. = 1
|
|
|
|
/datum/light_source/proc/parse_light_color()
|
|
if(light_color)
|
|
lum_r = GetRedPart(light_color) / 255
|
|
lum_g = GetGreenPart(light_color) / 255
|
|
lum_b = GetBluePart(light_color) / 255
|
|
else
|
|
lum_r = 1
|
|
lum_g = 1
|
|
lum_b = 1
|
|
|
|
/datum/light_source/proc/falloff(atom/movable/lighting_overlay/O)
|
|
#if LIGHTING_FALLOFF == 1 // circular
|
|
#if LIGHTING_RESOLUTION == 1
|
|
. = (O.x - source_turf.x)**2 + (O.y - source_turf.y)**2 + LIGHTING_HEIGHT
|
|
#else
|
|
. = (O.x - source_turf.x + O.xoffset)**2 + (O.y - source_turf.y + O.yoffset)**2 + LIGHTING_HEIGHT
|
|
#endif
|
|
|
|
#if LIGHTING_LAMBERTIAN == 1
|
|
. = CLAMP01((1 - CLAMP01(sqrt(.) / max(1,light_range))) * (1 / (sqrt(. + 1))))
|
|
#else
|
|
. = 1 - CLAMP01(sqrt(.) / max(1,light_range))
|
|
#endif
|
|
|
|
#elif LIGHTING_FALLOFF == 2 // square
|
|
#if LIGHTING_RESOLUTION == 1
|
|
. = abs(O.x - source_turf.x) + abs(O.y - source_turf.y) + LIGHTING_HEIGHT
|
|
#else
|
|
. = abs(O.x - source_turf.x + O.xoffset) + abs(O.y - source_turf.y + O.yoffset) + LIGHTING_HEIGHT
|
|
#endif
|
|
|
|
#if LIGHTING_LAMBERTIAN == 1
|
|
. = CLAMP01((1 - CLAMP01(. / max(1,light_range))) * (1 / (sqrt(.)**2 + )))
|
|
#else
|
|
. = 1 - CLAMP01(. / max(1,light_range))
|
|
#endif
|
|
#endif
|
|
|
|
/datum/light_source/proc/apply_lum()
|
|
applied = 1
|
|
if(istype(source_turf))
|
|
for(var/atom/movable/lighting_overlay/O in view(light_range, source_turf))
|
|
var/strength = light_power * falloff(O)
|
|
|
|
effect_r[O] = lum_r * strength
|
|
effect_g[O] = lum_g * strength
|
|
effect_b[O] = lum_b * strength
|
|
|
|
O.update_lumcount(lum_r * strength, lum_g * strength, lum_b * strength)
|
|
for(var/turf/T in view(light_range, source_turf))
|
|
if(!T.affecting_lights) T.affecting_lights = list()
|
|
T.affecting_lights += src
|
|
effect_turf += T
|
|
|
|
/datum/light_source/proc/remove_lum()
|
|
applied = 0
|
|
for(var/atom/movable/lighting_overlay/O in effect_r)
|
|
O.update_lumcount(-effect_r[O], -effect_g[O], -effect_b[O])
|
|
|
|
for(var/turf/T in effect_turf)
|
|
if(T.affecting_lights) T.affecting_lights -= src
|
|
|
|
effect_r.Cut()
|
|
effect_g.Cut()
|
|
effect_b.Cut()
|
|
effect_turf.Cut() |