diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm new file mode 100644 index 00000000000..fd95e7720c2 --- /dev/null +++ b/code/controllers/failsafe.dm @@ -0,0 +1,72 @@ +var/datum/controller/failsafe/Failsafe + +/datum/controller/failsafe // This thing pretty much just keeps poking the master controller + var/processing = 0 + var/processing_interval = 100 //poke the MC every 10 seconds + + var/MC_iteration = 0 + var/MC_defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one) + + var/lighting_iteration = 0 + var/lighting_defcon = 0 //alert level for lighting controller. + +/datum/controller/failsafe/New() + //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one) + if(Failsafe != src) + if(istype(Failsafe)) + del(Failsafe) + Failsafe = src + Failsafe.process() + + +/datum/controller/failsafe/proc/process() + processing = 1 + spawn(0) + set background = 1 + while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop + if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen. + if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller + + if(processing) + if(master_controller.processing) //only poke if these overrides aren't in effect + if(MC_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval + switch(MC_defcon) + if(0 to 3) + MC_defcon++ + if(4) + for(var/client/C in admin_list) + C << "Warning. The Master Controller has not fired in the last [MC_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks." + MC_defcon = 5 + if(5) + for(var/client/C in admin_list) + C << "Warning. The Master Controller has still not fired within the last [MC_defcon*processing_interval] ticks. Killing and restarting..." + new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process) + master_controller.process() //Start it rolling again + MC_defcon = 0 + else + MC_defcon = 0 + MC_iteration = controller_iteration + + if(lighting_controller.processing) + if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval + switch(lighting_defcon) + if(0 to 3) + lighting_defcon++ + if(4) + for(var/client/C in admin_list) + C << "Warning. The Lighting Controller has not fired in the last [lighting_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks." + lighting_defcon = 5 + if(5) + for(var/client/C in admin_list) + C << "Warning. The Lighting Controller has still not fired within the last [lighting_defcon*processing_interval] ticks. Killing and restarting..." + new /datum/controller/lighting() //replace the old lighting_controller (hence killing the old one's process) + lighting_controller.process() //Start it rolling again + lighting_defcon = 0 + else + lighting_defcon = 0 + lighting_iteration = lighting_controller.iteration + else + MC_defcon = 0 + lighting_defcon = 0 + + sleep(processing_interval) \ No newline at end of file diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 35330656159..a681dbaa83c 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -3,7 +3,6 @@ //WIP, needs lots of work still var/global/datum/controller/game_controller/master_controller //Set in world.New() -var/global/datum/failsafe/Failsafe var/global/controller_iteration = 0 var/global/last_tick_timeofday = world.timeofday @@ -30,7 +29,7 @@ datum/controller/game_controller datum/controller/game_controller/New() //There can be only one master_controller. Out with the old and in with the new. if(master_controller != src) - if(istype(master_controller,/datum/controller/game_controller)) + if(istype(master_controller)) Recover() del(master_controller) master_controller = src @@ -97,7 +96,7 @@ datum/controller/game_controller/proc/process() spawn(0) set background = 1 while(1) //far more efficient than recursively calling ourself - if(!Failsafe) new /datum/failsafe() + if(!Failsafe) new /datum/controller/failsafe() var/currenttime = world.timeofday last_tick_duration = (currenttime - last_tick_timeofday) / 10 @@ -247,65 +246,3 @@ datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now. msg += "\t [varname] = [varval]\n" world.log << msg -/datum/failsafe // This thing pretty much just keeps poking the master controller - var/spinning = 1 - var/current_iteration = 0 - var/ticks_per_spin = 100 //poke the MC every 10 seconds - var/defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one) - -/datum/failsafe/New() - //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one) - if(Failsafe && (Failsafe != src)) - del(Failsafe) - Failsafe = src - - current_iteration = controller_iteration - Failsafe.spin() - - -/datum/failsafe/proc/spin() - spawn(0) - set background = 1 - while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop - if(master_controller) - if(spinning && master_controller.processing) //only poke if these overrides aren't in effect - if(current_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval - switch(defcon) - if(0 to 3) - defcon++ - if(4) - for(var/client/C in admin_list) - if(C.holder) - C << "Warning. The Master Controller has not fired in the last [defcon*ticks_per_spin] ticks. Automatic restart in [ticks_per_spin] ticks." - defcon = 5 - if(5) - for(var/client/C in admin_list) - if(C.holder) - C << "Warning. The Master Controller has still not fired within the last [defcon*ticks_per_spin] ticks. Killing and restarting..." - new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process) - master_controller.process() //Start it rolling again - defcon = 0 - else - defcon = 0 - current_iteration = controller_iteration - else - defcon = 0 - else - new /datum/controller/game_controller() //replace the missing master_controller! This should never happen. - sleep(ticks_per_spin) - -//DEBUG VERBS -/* -/client/verb/spawn_MC() - new /datum/controller/game_controller() - - -/client/verb/spawn_FS() - new /datum/failsafe() - -/client/verb/machines_list() - for(var/i=1,i<=machines.len,i++) - var/machine = machines[i] - if(istype(machine,/datum)) world.log << machine:type - else world.log << machine -*/ \ No newline at end of file diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 04a1a47fed9..8e9fbf00701 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -1,7 +1,7 @@ //TODO: rewrite and standardise all controller datums to the datum/controller type //TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done -/client/proc/restart_controller(controller in list("Master","Lighting","Supply Shuttle")) +/client/proc/restart_controller(controller in list("Master","Failsafe","Lighting","Supply Shuttle")) set category = "Debug" set name = "Restart Controller" set desc = "Restart one of the various periodic loop controllers for the game (be careful!)" @@ -14,6 +14,9 @@ new /datum/controller/game_controller() master_controller.process() feedback_add_details("admin_verb","RMC") + if("Failsafe") + new /datum/controller/failsafe() + feedback_add_details("admin_verb","RFailsafe") if("Lighting") new /datum/controller/lighting() lighting_controller.process() @@ -25,7 +28,7 @@ return -/client/proc/debug_controller(controller in list("Master","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI")) +/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -35,6 +38,9 @@ if("Master") debug_variables(master_controller) feedback_add_details("admin_verb","DMC") + if("Failsafe") + debug_variables(Failsafe) + feedback_add_details("admin_verb","DFailsafe") if("Ticker") debug_variables(ticker) feedback_add_details("admin_verb","DTicker") diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index c4c127c11e4..6ee2a8aae4b 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -244,11 +244,11 @@ switch(fitting) if("tube") brightness = 8 - if(prob(10)) + if(prob(2)) broken(1) if("bulb") brightness = 4 - if(prob(25)) + if(prob(5)) broken(1) spawn(1) update(0) diff --git a/tgstation.dme b/tgstation.dme index 94e2561b8d3..a8b972874bb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6,220 +6,6 @@ // BEGIN_FILE_DIR #define FILE_DIR . -#define FILE_DIR "code" -#define FILE_DIR "code/ATMOSPHERICS" -#define FILE_DIR "code/ATMOSPHERICS/components" -#define FILE_DIR "code/ATMOSPHERICS/components/binary_devices" -#define FILE_DIR "code/ATMOSPHERICS/components/trinary_devices" -#define FILE_DIR "code/ATMOSPHERICS/components/unary" -#define FILE_DIR "code/controllers" -#define FILE_DIR "code/datums" -#define FILE_DIR "code/datums/diseases" -#define FILE_DIR "code/datums/helper_datums" -#define FILE_DIR "code/datums/organs" -#define FILE_DIR "code/datums/spells" -#define FILE_DIR "code/defines" -#define FILE_DIR "code/defines/obj" -#define FILE_DIR "code/defines/procs" -#define FILE_DIR "code/FEA" -#define FILE_DIR "code/game" -#define FILE_DIR "code/game/area" -#define FILE_DIR "code/game/gamemodes" -#define FILE_DIR "code/game/gamemodes/blob" -#define FILE_DIR "code/game/gamemodes/blob/blobs" -#define FILE_DIR "code/game/gamemodes/changeling" -#define FILE_DIR "code/game/gamemodes/cult" -#define FILE_DIR "code/game/gamemodes/events" -#define FILE_DIR "code/game/gamemodes/events/holidays" -#define FILE_DIR "code/game/gamemodes/extended" -#define FILE_DIR "code/game/gamemodes/malfunction" -#define FILE_DIR "code/game/gamemodes/meteor" -#define FILE_DIR "code/game/gamemodes/nuclear" -#define FILE_DIR "code/game/gamemodes/revolution" -#define FILE_DIR "code/game/gamemodes/sandbox" -#define FILE_DIR "code/game/gamemodes/traitor" -#define FILE_DIR "code/game/gamemodes/wizard" -#define FILE_DIR "code/game/jobs" -#define FILE_DIR "code/game/jobs/job" -#define FILE_DIR "code/game/machinery" -#define FILE_DIR "code/game/machinery/atmoalter" -#define FILE_DIR "code/game/machinery/bots" -#define FILE_DIR "code/game/machinery/camera" -#define FILE_DIR "code/game/machinery/computer" -#define FILE_DIR "code/game/machinery/doors" -#define FILE_DIR "code/game/machinery/embedded_controller" -#define FILE_DIR "code/game/machinery/kitchen" -#define FILE_DIR "code/game/machinery/pipe" -#define FILE_DIR "code/game/machinery/telecomms" -#define FILE_DIR "code/game/mecha" -#define FILE_DIR "code/game/mecha/combat" -#define FILE_DIR "code/game/mecha/equipment" -#define FILE_DIR "code/game/mecha/equipment/tools" -#define FILE_DIR "code/game/mecha/equipment/weapons" -#define FILE_DIR "code/game/mecha/medical" -#define FILE_DIR "code/game/mecha/working" -#define FILE_DIR "code/game/objects" -#define FILE_DIR "code/game/objects/effects" -#define FILE_DIR "code/game/objects/effects/decals" -#define FILE_DIR "code/game/objects/effects/decals/Cleanable" -#define FILE_DIR "code/game/objects/effects/spawners" -#define FILE_DIR "code/game/objects/items" -#define FILE_DIR "code/game/objects/items/devices" -#define FILE_DIR "code/game/objects/items/devices/PDA" -#define FILE_DIR "code/game/objects/items/devices/radio" -#define FILE_DIR "code/game/objects/items/robot" -#define FILE_DIR "code/game/objects/items/stacks" -#define FILE_DIR "code/game/objects/items/stacks/sheets" -#define FILE_DIR "code/game/objects/items/stacks/tiles" -#define FILE_DIR "code/game/objects/items/weapons" -#define FILE_DIR "code/game/objects/items/weapons/grenades" -#define FILE_DIR "code/game/objects/items/weapons/implants" -#define FILE_DIR "code/game/objects/items/weapons/secstorage" -#define FILE_DIR "code/game/objects/items/weapons/storage" -#define FILE_DIR "code/game/objects/items/weapons/tanks" -#define FILE_DIR "code/game/objects/structures" -#define FILE_DIR "code/game/objects/structures/crates_lockers" -#define FILE_DIR "code/game/objects/structures/crates_lockers/closets" -#define FILE_DIR "code/game/objects/structures/crates_lockers/closets/secure" -#define FILE_DIR "code/game/objects/structures/stool_bed_chair_nest" -#define FILE_DIR "code/game/turfs" -#define FILE_DIR "code/game/turfs/simulated" -#define FILE_DIR "code/game/turfs/space" -#define FILE_DIR "code/game/turfs/unsimulated" -#define FILE_DIR "code/game/vehicles" -#define FILE_DIR "code/game/vehicles/airtight" -#define FILE_DIR "code/game/verbs" -#define FILE_DIR "code/js" -#define FILE_DIR "code/modules" -#define FILE_DIR "code/modules/admin" -#define FILE_DIR "code/modules/admin/DB ban" -#define FILE_DIR "code/modules/admin/verbs" -#define FILE_DIR "code/modules/assembly" -#define FILE_DIR "code/modules/awaymissions" -#define FILE_DIR "code/modules/awaymissions/maploader" -#define FILE_DIR "code/modules/client" -#define FILE_DIR "code/modules/clothing" -#define FILE_DIR "code/modules/clothing/glasses" -#define FILE_DIR "code/modules/clothing/gloves" -#define FILE_DIR "code/modules/clothing/head" -#define FILE_DIR "code/modules/clothing/masks" -#define FILE_DIR "code/modules/clothing/shoes" -#define FILE_DIR "code/modules/clothing/spacesuits" -#define FILE_DIR "code/modules/clothing/suits" -#define FILE_DIR "code/modules/clothing/under" -#define FILE_DIR "code/modules/clothing/under/jobs" -#define FILE_DIR "code/modules/critters" -#define FILE_DIR "code/modules/critters/hivebots" -#define FILE_DIR "code/modules/detectivework" -#define FILE_DIR "code/modules/flufftext" -#define FILE_DIR "code/modules/food" -#define FILE_DIR "code/modules/library" -#define FILE_DIR "code/modules/liquid" -#define FILE_DIR "code/modules/mining" -#define FILE_DIR "code/modules/mob" -#define FILE_DIR "code/modules/mob/dead" -#define FILE_DIR "code/modules/mob/dead/observer" -#define FILE_DIR "code/modules/mob/living" -#define FILE_DIR "code/modules/mob/living/blob" -#define FILE_DIR "code/modules/mob/living/carbon" -#define FILE_DIR "code/modules/mob/living/carbon/alien" -#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid" -#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid/caste" -#define FILE_DIR "code/modules/mob/living/carbon/alien/larva" -#define FILE_DIR "code/modules/mob/living/carbon/alien/special" -#define FILE_DIR "code/modules/mob/living/carbon/brain" -#define FILE_DIR "code/modules/mob/living/carbon/human" -#define FILE_DIR "code/modules/mob/living/carbon/metroid" -#define FILE_DIR "code/modules/mob/living/carbon/monkey" -#define FILE_DIR "code/modules/mob/living/silicon" -#define FILE_DIR "code/modules/mob/living/silicon/ai" -#define FILE_DIR "code/modules/mob/living/silicon/ai/freelook" -#define FILE_DIR "code/modules/mob/living/silicon/decoy" -#define FILE_DIR "code/modules/mob/living/silicon/pai" -#define FILE_DIR "code/modules/mob/living/silicon/robot" -#define FILE_DIR "code/modules/mob/living/simple_animal" -#define FILE_DIR "code/modules/mob/new_player" -#define FILE_DIR "code/modules/paperwork" -#define FILE_DIR "code/modules/power" -#define FILE_DIR "code/modules/power/antimatter" -#define FILE_DIR "code/modules/power/singularity" -#define FILE_DIR "code/modules/power/singularity/particle_accelerator" -#define FILE_DIR "code/modules/projectiles" -#define FILE_DIR "code/modules/projectiles/ammunition" -#define FILE_DIR "code/modules/projectiles/guns" -#define FILE_DIR "code/modules/projectiles/guns/energy" -#define FILE_DIR "code/modules/projectiles/guns/projectile" -#define FILE_DIR "code/modules/projectiles/projectile" -#define FILE_DIR "code/modules/reagents" -#define FILE_DIR "code/modules/reagents/reagent_containers" -#define FILE_DIR "code/modules/reagents/reagent_containers/food" -#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks" -#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks/bottle" -#define FILE_DIR "code/modules/reagents/reagent_containers/food/snacks" -#define FILE_DIR "code/modules/reagents/reagent_containers/glass" -#define FILE_DIR "code/modules/reagents/reagent_containers/glass/bottle" -#define FILE_DIR "code/modules/recycling" -#define FILE_DIR "code/modules/research" -#define FILE_DIR "code/modules/scripting" -#define FILE_DIR "code/modules/scripting/AST" -#define FILE_DIR "code/modules/scripting/AST/Operators" -#define FILE_DIR "code/modules/scripting/Implementations" -#define FILE_DIR "code/modules/scripting/Interpreter" -#define FILE_DIR "code/modules/scripting/Parser" -#define FILE_DIR "code/modules/scripting/Scanner" -#define FILE_DIR "code/modules/security levels" -#define FILE_DIR "code/unused" -#define FILE_DIR "code/unused/beast" -#define FILE_DIR "code/unused/computer2" -#define FILE_DIR "code/unused/disease2" -#define FILE_DIR "code/unused/gamemodes" -#define FILE_DIR "code/unused/hivebot" -#define FILE_DIR "code/unused/mining" -#define FILE_DIR "code/unused/optics" -#define FILE_DIR "code/unused/pda2" -#define FILE_DIR "code/unused/powerarmor" -#define FILE_DIR "code/unused/spacecraft" -#define FILE_DIR "code/WorkInProgress" -#define FILE_DIR "code/WorkInProgress/carn" -#define FILE_DIR "code/WorkInProgress/mapload" -#define FILE_DIR "code/WorkInProgress/organs" -#define FILE_DIR "code/WorkInProgress/virus2" -#define FILE_DIR "html" -#define FILE_DIR "icons" -#define FILE_DIR "icons/effects" -#define FILE_DIR "icons/mecha" -#define FILE_DIR "icons/misc" -#define FILE_DIR "icons/mob" -#define FILE_DIR "icons/obj" -#define FILE_DIR "icons/obj/assemblies" -#define FILE_DIR "icons/obj/atmospherics" -#define FILE_DIR "icons/obj/clothing" -#define FILE_DIR "icons/obj/doors" -#define FILE_DIR "icons/obj/machines" -#define FILE_DIR "icons/obj/pipes" -#define FILE_DIR "icons/pda_icons" -#define FILE_DIR "icons/spideros_icons" -#define FILE_DIR "icons/Testing" -#define FILE_DIR "icons/turf" -#define FILE_DIR "icons/vehicles" -#define FILE_DIR "icons/vending_icons" -#define FILE_DIR "interface" -#define FILE_DIR "maps" -#define FILE_DIR "maps/RandomZLevels" -#define FILE_DIR "sound" -#define FILE_DIR "sound/AI" -#define FILE_DIR "sound/ambience" -#define FILE_DIR "sound/effects" -#define FILE_DIR "sound/hallucinations" -#define FILE_DIR "sound/items" -#define FILE_DIR "sound/machines" -#define FILE_DIR "sound/mecha" -#define FILE_DIR "sound/misc" -#define FILE_DIR "sound/piano" -#define FILE_DIR "sound/voice" -#define FILE_DIR "sound/weapons" -#define FILE_DIR "tools" -#define FILE_DIR "tools/Redirector" // END_FILE_DIR // BEGIN_PREFERENCES @@ -260,6 +46,7 @@ #include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm" #include "code\controllers\_DynamicAreaLighting_TG.dm" #include "code\controllers\configuration.dm" +#include "code\controllers\failsafe.dm" #include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm"