Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP/DNM] New Day/Night System #856

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 0 additions & 116 deletions code/controllers/subsystem/nightcycle.dm

This file was deleted.

62 changes: 30 additions & 32 deletions code/controllers/subsystem/sun.dm
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
#define DAYLENGTH (10 MINUTES)
GLOBAL_LIST_INIT(daylight_turfs, typecacheof(list(
/turf/open/indestructible/ground/outside,
/turf/open/floor/plating/f13/outside)))

SUBSYSTEM_DEF(sun)
name = "Sun"
wait = 600
wait = 2 MINUTES
flags = SS_NO_TICK_CHECK|SS_NO_INIT
var/angle
var/dx
var/dy
var/rate
var/tmp/angle
var/tmp/dir
var/tmp/power
var/tmp/dx
var/tmp/dz
var/list/solars = list()

/datum/controller/subsystem/sun/PreInit()
angle = rand (0,360) // the station position to the sun is randomised at round start
rate = rand(50,200)/100 // 50% - 200% of standard rotation
if(prob(50)) // same chance to rotate clockwise than counter-clockwise
rate = -rate
fire()

/datum/controller/subsystem/sun/stat_entry(msg)
..("P:[solars.len]")
..("A:[angle] P:[solars.len]")

/datum/controller/subsystem/sun/fire()
angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate

// now calculate and cache the (dx,dy) increments for line drawing
var/s = sin(angle)
var/c = cos(angle)

// Either "abs(s) < abs(c)" or "abs(s) >= abs(c)"
// In both cases, the greater is greater than 0, so, no "if 0" check is needed for the divisions

if(abs(s) < abs(c))
dx = s / abs(c)
dy = c / abs(c)
else
dx = s / abs(s)
dy = c / abs(s)

update_angle(((world.realtime/DAYLENGTH * 360) - 90) % 360) // 0 to 180 is up; 0 to 30 and 150 to 180 is sunrise/sunset; 90 is noon
//now tell the solar control computers to update their status and linked devices
for(var/obj/machinery/power/solar_control/SC in solars)
if(!SC.powernet)
solars.Remove(SC)
continue
SC.update()







/datum/controller/subsystem/sun/proc/update_angle(var/ang)
if(!SSsunlight)
return
angle = ang
power = max(sin(angle*2)**2, 75/10000)
SSsunlight.set_overall_light(SSsunlight.sun_accuracy * 1.2, power, getcolor())


/datum/controller/subsystem/sun/proc/getcolor()
switch(angle)
if(180 to 360)
return "#000000"
if(30 to 150)
return "#fdfbd3"
var/dist_from_horizon = angle < 90 ? 30-angle : angle-150
return BlendRGB("#fdfbd3", "#fd5e53", 1 - dist_from_horizon/30)
54 changes: 54 additions & 0 deletions code/controllers/subsystem/sunlight.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
SUBSYSTEM_DEF(sunlight)
name = "Sunlight"
flags = SS_NO_FIRE

var/list/light_points = list()
var/sun_target_z = 2
var/sun_accuracy = 8

var/list/presets

/datum/controller/subsystem/sunlight/New()
NEW_SS_GLOBAL(SSsunlight)

/datum/controller/subsystem/sunlight/stat_entry()
..("A:[sun_accuracy] LP:[light_points.len] Z:[sun_target_z]")

/datum/controller/subsystem/sunlight/Initialize()
var/thing
var/turf/T
for (thing in block(locate(1, 1, sun_target_z), locate(world.maxx, world.maxy, sun_target_z)))
T = thing
if (!(T.x % sun_accuracy) && !(T.y % sun_accuracy))
light_points += new /atom/movable/sunobj(thing)
CHECK_TICK

log_game("sunlight: [light_points.len] sun emitters.")
..()

/datum/controller/subsystem/sunlight/proc/set_overall_light(...)
. = 0
for (var/thing in light_points)
var/atom/movable/AM = thing
AM.set_light(arglist(args))
.++
CHECK_TICK

/atom/movable/sunobj
name = "sunlight emitter"
desc = "Weren't you told to never look directly at the sun? (but seriously, you shouldn't see this)"
light_novis = TRUE
light_range = 16
mouse_opacity = FALSE

/atom/movable/sunobj/Destroy(force = FALSE)
if (!force)
stack_trace("Something attempted to delete a sunobj!")
return QDEL_HINT_LETMELIVE

SSsunlight.light_points -= src
return ..()

/atom/movable/sunobj/Initialize()
light_range = CEILING(SSsunlight.sun_accuracy * 1.2, 1)
return ..()
3 changes: 3 additions & 0 deletions code/modules/lighting/lighting_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
var/light_power = 1 // Intensity of the light.
var/light_range = 0 // Range in tiles of the light.
var/light_color // Hexadecimal RGB string representing the colour of the light.
var/light_novis // If TRUE, visibility checks will be skipped when calculating this light.

var/tmp/datum/light_source/light // Our light source. Don't fuck with this directly unless you have a good reason!
var/tmp/list/light_sources // Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
Expand Down Expand Up @@ -46,6 +47,8 @@

if (light) // Update the light or create it if it does not exist.
light.update(.)
else if (light_novis)
light = new/datum/light_source/novis(src, .)
else
light = new/datum/light_source(src, .)

Expand Down
33 changes: 23 additions & 10 deletions code/modules/lighting/lighting_source.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

var/lightFlag = NONE //tags such as GLOBAL_LIGHTING - No other use so far

var/skip_falloff = FALSE // ONLY for use with sunlight, behavior is undefined if TRUE on regular sources.

/datum/light_source/New(var/atom/owner, var/atom/top)
source_atom = owner // Set our new owner.
LAZYADD(source_atom.light_sources, src)
Expand Down Expand Up @@ -121,6 +123,20 @@
// The braces and semicolons are there to be able to do this on a single line.
#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))

// APPLY_CORNER without LUM_FALLOFF.
#define APPLY_CORNER_SIMPLE(C) \
. = light_power; \
var/OLD = effect_str[C]; \
\
effect_str[C] = .; \
\
C.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_b) - (OLD * applied_lum_b) \
);

#define APPLY_CORNER(C) \
. = LUM_FALLOFF(C, pixel_turf); \
. *= light_power; \
Expand Down Expand Up @@ -171,9 +187,14 @@
REMOVE_CORNER(C)
effect_str[C] = 0

APPLY_CORNER(C)

if (skip_falloff)
APPLY_CORNER_SIMPLE(C)
else
APPLY_CORNER(C)
UNSETEMPTY(effect_str)

// If you update this, update the equivalent proc in lighting_source_novis.dm.
/datum/light_source/proc/update_corners()
var/update = FALSE
var/atom/source_atom = src.source_atom
Expand Down Expand Up @@ -321,12 +342,4 @@
return 0
else
return 0
return 1




#undef EFFECT_UPDATE
#undef LUM_FALLOFF
#undef REMOVE_CORNER
#undef APPLY_CORNER
return 1
Loading