diff --git a/code/__DEFINES/dcs/signals/signals_area.dm b/code/__DEFINES/dcs/signals/signals_area.dm index 0cd24d69ed0548..762431788f2581 100644 --- a/code/__DEFINES/dcs/signals/signals_area.dm +++ b/code/__DEFINES/dcs/signals/signals_area.dm @@ -12,8 +12,6 @@ #define COMSIG_ENTER_AREA "enter_area" ///from base of area/Exited(): (area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info. #define COMSIG_EXIT_AREA "exit_area" -///from base of /datum/controller/subsystem/atoms/proc/InitAtom(): (atom/new_atom) -#define COMSIG_AREA_INITIALIZED_IN "area_initialized_in" // Alarm listener datum signals ///Sent when an alarm is fired and an alarm listener has tracked onto it (alarm, area/source_area) diff --git a/code/__DEFINES/radioactive_nebula.dm b/code/__DEFINES/radioactive_nebula.dm new file mode 100644 index 00000000000000..68849ca1bc2f60 --- /dev/null +++ b/code/__DEFINES/radioactive_nebula.dm @@ -0,0 +1,2 @@ +/// Name of the glow we use for the radioation effect outside +#define GLOW_NEBULA "glow_nebula" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 0bc3c01074824f..2e827f38f7dc7b 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -119,9 +119,12 @@ /// Subsystem initialized sucessfully. #define SS_INIT_SUCCESS 2 -/// Successful, but don't print anything. Useful if subsystem was disabled. +/// If your system doesn't need to be initialized (by being disabled or something) #define SS_INIT_NO_NEED 3 +/// Succesfully initialized, BUT do not announce it to players (generally to hide game mechanics it would otherwise spoil) +#define SS_INIT_NO_MESSAGE 4 + //! ### SS initialization load orders // Subsystem init_order, from highest priority to lowest priority // Subsystems shutdown in the reverse of the order they initialize in diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 1697d3e41b76c3..6e4c21fba208b5 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -290,6 +290,7 @@ GLOBAL_REAL(Master, /datum/controller/master) SS_INIT_NONE, SS_INIT_SUCCESS, SS_INIT_NO_NEED, + SS_INIT_NO_MESSAGE, ) if (subsystem.flags & SS_NO_INIT || subsystem.initialized) //Don't init SSs with the corresponding flag or if they already are initialized @@ -335,7 +336,7 @@ GLOBAL_REAL(Master, /datum/controller/master) if(SS_INIT_FAILURE) message_prefix = "Failed to initialize [subsystem.name] subsystem after" chat_warning = TRUE - if(SS_INIT_SUCCESS) + if(SS_INIT_SUCCESS, SS_INIT_NO_MESSAGE) message_prefix = "Initialized [subsystem.name] subsystem within" if(SS_INIT_NO_NEED) // This SS is disabled or is otherwise shy. @@ -348,7 +349,8 @@ GLOBAL_REAL(Master, /datum/controller/master) var/message = "[message_prefix] [seconds] second[seconds == 1 ? "" : "s"]!" var/chat_message = chat_warning ? span_boldwarning(message) : span_boldannounce(message) - to_chat(world, chat_message) + if(result != SS_INIT_NO_MESSAGE) + to_chat(world, chat_message) log_world(message) /datum/controller/master/proc/SetRunLevel(new_runlevel) diff --git a/code/controllers/subsystem/radioactive_nebula.dm b/code/controllers/subsystem/radioactive_nebula.dm new file mode 100644 index 00000000000000..3b11a7870af98a --- /dev/null +++ b/code/controllers/subsystem/radioactive_nebula.dm @@ -0,0 +1,64 @@ +/// Trait for tracking if something already has the fake irradiation effect, so we don't waste time on effect operations if otherwise unnecessary +#define TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED "radioactive_nebula_fake_irradiated" + +/// Controls making objects irradiated when Radioactive Nebula is in effect. +SUBSYSTEM_DEF(radioactive_nebula) + name = "Radioactive Nebula" + flags = SS_BACKGROUND + wait = 30 SECONDS + + VAR_PRIVATE + datum/station_trait/nebula/hostile/radiation/radioactive_nebula + +/datum/controller/subsystem/radioactive_nebula/Initialize() + radioactive_nebula = locate() in SSstation.station_traits + if (!radioactive_nebula) + can_fire = FALSE + return SS_INIT_NO_NEED + + // We don't *really* care that this happens by the time the server is ready to play. + ASYNC + irradiate_everything() + + // Don't leak that the station trait has been picked + return SS_INIT_NO_MESSAGE + +/// Makes something appear irradiated for the purposes of the Radioactive Nebula +/datum/controller/subsystem/radioactive_nebula/proc/fake_irradiate(atom/movable/target) + if (HAS_TRAIT(target, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED)) + return + + ADD_TRAIT(target, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED, REF(src)) + + if(iscarbon(target))//Don't actually make EVERY. SINGLE. THING. RADIOACTIVE. Just irradiate people + target.AddComponent( \ + /datum/component/radioactive_exposure, \ + minimum_exposure_time = NEBULA_RADIATION_MINIMUM_EXPOSURE_TIME, \ + irradiation_chance_base = RADIATION_EXPOSURE_NEBULA_BASE_CHANCE, \ + irradiation_chance_increment = RADIATION_EXPOSURE_NEBULA_CHANCE_INCREMENT, \ + irradiation_interval = RADIATION_EXPOSURE_NEBULA_CHECK_INTERVAL, \ + source = src, \ + radioactive_areas = radioactive_nebula.radioactive_areas, \ + ) + else if(isobj(target)) //and fake the rest + //outline clashes too much with other outlines and creates pretty ugly lines + target.add_filter(GLOW_NEBULA, 2, list("type" = "drop_shadow", "color" = radioactive_nebula.nebula_radglow, "size" = 2)) + +/datum/controller/subsystem/radioactive_nebula/fire() + irradiate_everything() + +/// Loop through radioactive space (with lag checks) and make it all radioactive! +/datum/controller/subsystem/radioactive_nebula/proc/irradiate_everything() + for (var/area/area as anything in get_areas(radioactive_nebula.radioactive_areas)) + for (var/turf/turf as anything in area.get_contained_turfs()) + for (var/atom/movable/target as anything in turf) + fake_irradiate(target) + + CHECK_TICK + +/// Remove the fake radiation. The compontent we add to mobs handles its own removal +/datum/controller/subsystem/radioactive_nebula/proc/fake_unirradiate(atom/movable/leaver) + REMOVE_TRAIT(leaver, TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED, REF(src)) + leaver.remove_filter(GLOW_NEBULA) + +#undef TRAIT_RADIOACTIVE_NEBULA_FAKE_IRRADIATED diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm index 6203ef46899455..901ec0ca115f4c 100644 --- a/code/datums/station_traits/negative_traits.dm +++ b/code/datums/station_traits/negative_traits.dm @@ -509,9 +509,6 @@ nebula.add_shielder(shielder, shielding_proc) -/// Name of the glow we use for the radioation effect outside -#define GLOW_NEBULA "glow_nebula" - ///The station will be inside a radioactive nebula! Space is radioactive and the station needs to start setting up nebula shielding /datum/station_trait/nebula/hostile/radiation name = "Radioactive Nebula" @@ -549,7 +546,7 @@ . = ..() for(var/area/target as anything in get_areas(radioactive_areas)) - RegisterSignals(target, list(COMSIG_AREA_ENTERED, COMSIG_AREA_INITIALIZED_IN), PROC_REF(on_entered)) + RegisterSignal(target, COMSIG_AREA_ENTERED, PROC_REF(on_entered)) RegisterSignal(target, COMSIG_AREA_EXITED, PROC_REF(on_exited)) /datum/station_trait/nebula/hostile/radiation/on_round_start() @@ -581,27 +578,18 @@ /datum/station_trait/nebula/hostile/radiation/proc/on_entered(area/space, atom/movable/enterer, area/old_area) SIGNAL_HANDLER - if(iscarbon(enterer))//Don't actually make EVERY. SINGLE. THING. RADIOACTIVE. Just irradiate people - if(!istype(old_area, radioactive_areas)) //old area wasnt radioactive - enterer.AddComponent( \ - /datum/component/radioactive_exposure, \ - minimum_exposure_time = NEBULA_RADIATION_MINIMUM_EXPOSURE_TIME, \ - irradiation_chance_base = RADIATION_EXPOSURE_NEBULA_BASE_CHANCE, \ - irradiation_chance_increment = RADIATION_EXPOSURE_NEBULA_CHANCE_INCREMENT, \ - irradiation_interval = RADIATION_EXPOSURE_NEBULA_CHECK_INTERVAL, \ - source = src, \ - radioactive_areas = radioactive_areas, \ - ) + // Old area was radioactive, so what's the point. nothing changes. nothing ever does. also make sure the subsystem is alive before we give it food + if (istype(old_area, radioactive_areas) || !SSradioactive_nebula.initialized) + return - else if(isobj(enterer)) //and fake the rest - //outline clashes too much with other outlines and creates pretty ugly lines - enterer.add_filter(GLOW_NEBULA, 2, list("type" = "drop_shadow", "color" = nebula_radglow, "size" = 2)) + SSradioactive_nebula.fake_irradiate(enterer) ///Called when an atom leaves space, so we can remove the radiation effect /datum/station_trait/nebula/hostile/radiation/proc/on_exited(area/space, atom/movable/exiter, direction) SIGNAL_HANDLER - exiter.remove_filter(GLOW_NEBULA) + SSradioactive_nebula.fake_unirradiate(exiter) + // The component handles its own removal /datum/station_trait/nebula/hostile/radiation/apply_nebula_effect(effect_strength = 0) diff --git a/code/game/atoms_initializing_EXPENSIVE.dm b/code/game/atoms_initializing_EXPENSIVE.dm index ae729ad1f48849..1ecc6390edc345 100644 --- a/code/game/atoms_initializing_EXPENSIVE.dm +++ b/code/game/atoms_initializing_EXPENSIVE.dm @@ -47,9 +47,6 @@ if(location) /// Sends a signal that the new atom `src`, has been created at `loc` SEND_SIGNAL(location, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, A, arguments[1]) - var/area/atom_area = get_area(location) - if(atom_area) - SEND_SIGNAL(atom_area, COMSIG_AREA_INITIALIZED_IN, A) if(created_atoms && from_template && ispath(the_type, /atom/movable))//we only want to populate the list with movables created_atoms += A.get_all_contents() diff --git a/tgstation.dme b/tgstation.dme index a3b7c06dffcf07..f83a39b628c1ef 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -176,6 +176,7 @@ #include "code\__DEFINES\quirks.dm" #include "code\__DEFINES\radiation.dm" #include "code\__DEFINES\radio.dm" +#include "code\__DEFINES\radioactive_nebula.dm" #include "code\__DEFINES\reactions.dm" #include "code\__DEFINES\reagents.dm" #include "code\__DEFINES\reagents_specific_heat.dm" @@ -625,6 +626,7 @@ #include "code\controllers\subsystem\profiler.dm" #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" +#include "code\controllers\subsystem\radioactive_nebula.dm" #include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\restaurant.dm" #include "code\controllers\subsystem\runechat.dm"