mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-20 17:56:37 +01:00
201 lines
5.9 KiB
Plaintext
201 lines
5.9 KiB
Plaintext
SUBSYSTEM_DEF(planets)
|
|
name = "Planets"
|
|
init_order = INIT_ORDER_PLANETS
|
|
priority = FIRE_PRIORITY_PLANETS
|
|
wait = 2 SECONDS
|
|
subsystem_flags = SS_BACKGROUND
|
|
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
|
|
|
/**
|
|
* Global mutex used by planet code to ensure no more than one
|
|
* is updating sunlight at the same time.
|
|
* * Because BYOND is fundamentally single threaded,
|
|
* trying to do sunlight update in parallel would just
|
|
* make it more obvious to the player that it's slow and end up
|
|
* wasting CPU via context switching.
|
|
* * This is only checked in the subsystem.
|
|
*/
|
|
var/static/sun_lighting_update_mutex = FALSE
|
|
|
|
var/static/list/new_outdoor_turfs = list()
|
|
var/static/list/new_outdoor_walls = list()
|
|
|
|
var/static/list/planets = list()
|
|
var/static/list/z_to_planet = list()
|
|
|
|
var/static/list/currentrun = list()
|
|
|
|
var/static/list/needs_temp_update = list()
|
|
|
|
/datum/controller/subsystem/planets/Initialize(timeofday)
|
|
report_progress("Initializing planetary weather.")
|
|
allocateTurfs(TRUE)
|
|
fire() // Fire once to preemptively set up weather and planetary ambient lighting.
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/planets/on_max_z_changed(old_z_count, new_z_count)
|
|
. = ..()
|
|
z_to_planet.len = new_z_count
|
|
|
|
/datum/controller/subsystem/planets/proc/legacy_planet_assert(z_index, planet_path)
|
|
var/datum/planet/existing = locate(planet_path) in planets
|
|
if(isnull(existing))
|
|
existing = new planet_path
|
|
planets += existing
|
|
z_to_planet[z_index] = existing
|
|
LAZYDISTINCTADD(existing.expected_z_levels, z_index)
|
|
|
|
/datum/controller/subsystem/planets/proc/addTurf(turf/T)
|
|
if(T.turf_flags & (TURF_PLANET_QUEUED | TURF_PLANET_REGISTERED))
|
|
return
|
|
T.turf_flags |= TURF_PLANET_QUEUED
|
|
new_outdoor_turfs += T
|
|
|
|
/datum/controller/subsystem/planets/proc/addWall(turf/T)
|
|
if(T.turf_flags & (TURF_PLANET_QUEUED | TURF_PLANET_REGISTERED))
|
|
return
|
|
T.turf_flags |= TURF_PLANET_QUEUED
|
|
new_outdoor_walls += T
|
|
|
|
/datum/controller/subsystem/planets/proc/removeTurf(turf/T)
|
|
new_outdoor_turfs -= T
|
|
T.turf_flags &= ~(TURF_PLANET_QUEUED | TURF_PLANET_REGISTERED)
|
|
if(z_to_planet.len >= T.z)
|
|
var/datum/planet/P = z_to_planet[T.z]
|
|
if(!P)
|
|
return
|
|
P.planet_floors -= T
|
|
T.vis_contents -= P.weather_holder.visuals
|
|
T.vis_contents -= P.weather_holder.special_visuals
|
|
|
|
/datum/controller/subsystem/planets/proc/removeWall(turf/T)
|
|
new_outdoor_walls -= T
|
|
T.turf_flags &= ~(TURF_PLANET_QUEUED | TURF_PLANET_REGISTERED)
|
|
if(z_to_planet.len >= T.z)
|
|
var/datum/planet/P = z_to_planet[T.z]
|
|
if(!P)
|
|
return
|
|
P.planet_walls -= T
|
|
T.vis_contents -= P.weather_holder.visuals
|
|
T.vis_contents -= P.weather_holder.special_visuals
|
|
|
|
/datum/controller/subsystem/planets/proc/allocateTurfs(initial)
|
|
// if initial we're going to do optimizations
|
|
var/planet_z_count = z_to_planet.len
|
|
if(initial)
|
|
// make sure no duplicates are there
|
|
for(var/turf/simulated/S in new_outdoor_turfs)
|
|
S.turf_flags &= ~TURF_PLANET_QUEUED
|
|
S.turf_flags |= TURF_PLANET_REGISTERED
|
|
if(planet_z_count < S.z)
|
|
continue
|
|
var/datum/planet/P = z_to_planet[S.z]
|
|
if(!P)
|
|
continue
|
|
P.planet_floors += S
|
|
S.vis_contents |= P.weather_holder.visuals
|
|
S.vis_contents |= P.weather_holder.special_visuals
|
|
CHECK_TICK
|
|
for(var/turf/unsimulated/wall/planetary/S in new_outdoor_walls)
|
|
S.turf_flags &= ~TURF_PLANET_QUEUED
|
|
S.turf_flags |= TURF_PLANET_REGISTERED
|
|
if(planet_z_count < S.z)
|
|
continue
|
|
var/datum/planet/P = z_to_planet[S.z]
|
|
if(!P)
|
|
continue
|
|
P.planet_walls += S
|
|
CHECK_TICK
|
|
new_outdoor_turfs = list()
|
|
new_outdoor_walls = list()
|
|
return
|
|
var/list/curr = new_outdoor_turfs
|
|
while(curr.len)
|
|
var/turf/unsimulated/wall/planetary/S = curr[curr.len]
|
|
S.turf_flags &= ~TURF_PLANET_QUEUED
|
|
S.turf_flags |= TURF_PLANET_REGISTERED
|
|
curr.len--
|
|
if(!istype(S))
|
|
continue
|
|
if(planet_z_count < S.z)
|
|
continue
|
|
var/datum/planet/P = z_to_planet[S.z]
|
|
if(!P)
|
|
continue
|
|
P.planet_floors += S
|
|
S.vis_contents |= P.weather_holder.visuals
|
|
S.vis_contents |= P.weather_holder.special_visuals
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
curr = new_outdoor_walls
|
|
while(curr.len)
|
|
var/turf/unsimulated/wall/planetary/S = curr[curr.len]
|
|
S.turf_flags &= ~TURF_PLANET_QUEUED
|
|
S.turf_flags |= TURF_PLANET_REGISTERED
|
|
curr.len--
|
|
if(!istype(S))
|
|
continue
|
|
if(planet_z_count < S.z)
|
|
continue
|
|
var/datum/planet/P = z_to_planet[S.z]
|
|
if(!P)
|
|
continue
|
|
P.planet_walls += S
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/planets/fire(resumed = FALSE)
|
|
if(new_outdoor_turfs.len || new_outdoor_walls.len)
|
|
allocateTurfs()
|
|
|
|
if(!resumed)
|
|
src.currentrun = planets.Copy()
|
|
|
|
var/list/needs_temp_update = src.needs_temp_update
|
|
while(needs_temp_update.len)
|
|
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
|
|
needs_temp_update.len--
|
|
updateTemp(P)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
var/list/currentrun = src.currentrun
|
|
var/dt = nominal_dt_s
|
|
while(currentrun.len)
|
|
var/datum/planet/P = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
|
|
// run
|
|
// this is not very subsystem of me but i don't care man this fixes the
|
|
// bug where the server lags to a halt because this is
|
|
// still better than the old behavior
|
|
if(P.sun_lighting_update_dirty && !sun_lighting_update_mutex)
|
|
run_sun_update(P)
|
|
|
|
P.process(dt, last_fire)
|
|
|
|
//Temperature needs updating
|
|
if(P.needs_work & PLANET_PROCESS_TEMP)
|
|
P.needs_work &= ~PLANET_PROCESS_TEMP
|
|
needs_temp_update |= P
|
|
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/planets/proc/updateTemp(datum/planet/P)
|
|
//Set new temperatures
|
|
for(var/turf/T in P.planet_walls)
|
|
T.sector_set_temperature(P.weather_holder.temperature)
|
|
CHECK_TICK
|
|
|
|
/datum/controller/subsystem/planets/proc/run_sun_update(datum/planet/planet)
|
|
spawn(0)
|
|
run_sun_update_blocking(planet)
|
|
|
|
/datum/controller/subsystem/planets/proc/run_sun_update_blocking(datum/planet/planet)
|
|
if(sun_lighting_update_mutex)
|
|
return
|
|
sun_lighting_update_mutex = TRUE
|
|
planet.update_sun_lighting()
|
|
sun_lighting_update_mutex = FALSE
|