#define BAD_INIT_QDEL_BEFORE 1 #define BAD_INIT_DIDNT_INIT 2 #define BAD_INIT_SLEPT 4 #define BAD_INIT_NO_HINT 8 SUBSYSTEM_DEF(atoms) name = "Atoms" init_order = INIT_ORDER_ATOMS flags = SS_NO_FIRE var/old_initialized var/list/late_loaders = list() var/list/BadInitializeCalls = list() initialized = INITIALIZATION_INSSATOMS /datum/controller/subsystem/atoms/Initialize(timeofday) GLOB.fire_overlay.appearance_flags = RESET_COLOR setupGenetics() //to set the mutations' sequence initialized = INITIALIZATION_INNEW_MAPLOAD InitializeAtoms() initialized = INITIALIZATION_INNEW_REGULAR return ..() /datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) if(initialized == INITIALIZATION_INSSATOMS) return old_initialized = initialized initialized = INITIALIZATION_INNEW_MAPLOAD var/count var/list/mapload_arg = list(TRUE) if(atoms) count = atoms.len for(var/I in 1 to count) var/atom/A = atoms[I] if(!(A.flags_1 & INITIALIZED_1)) InitAtom(A, mapload_arg) CHECK_TICK else count = 0 for(var/atom/A in world) if(!(A.flags_1 & INITIALIZED_1)) InitAtom(A, mapload_arg) ++count CHECK_TICK testing("Initialized [count] atoms") pass(count) initialized = old_initialized if(late_loaders.len) for(var/I in 1 to late_loaders.len) var/atom/A = late_loaders[I] A.LateInitialize() testing("Late initialized [late_loaders.len] atoms") late_loaders.Cut() /// Init this specific atom /datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) var/the_type = A.type if(QDELING(A)) BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE return TRUE var/start_tick = world.time var/result = A.Initialize(arglist(arguments)) if(start_tick != world.time) BadInitializeCalls[the_type] |= BAD_INIT_SLEPT var/qdeleted = FALSE if(result != INITIALIZE_HINT_NORMAL) switch(result) if(INITIALIZE_HINT_LATELOAD) if(arguments[1]) //mapload late_loaders += A else A.LateInitialize() if(INITIALIZE_HINT_QDEL) qdel(A) qdeleted = TRUE else BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT if(!A) //possible harddel qdeleted = TRUE else if(!(A.flags_1 & INITIALIZED_1)) BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT else SEND_SIGNAL(A,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) return qdeleted || QDELING(A) /datum/controller/subsystem/atoms/proc/map_loader_begin() old_initialized = initialized initialized = INITIALIZATION_INSSATOMS /datum/controller/subsystem/atoms/proc/map_loader_stop() initialized = old_initialized /datum/controller/subsystem/atoms/Recover() initialized = SSatoms.initialized if(initialized == INITIALIZATION_INNEW_MAPLOAD) InitializeAtoms() old_initialized = SSatoms.old_initialized BadInitializeCalls = SSatoms.BadInitializeCalls /datum/controller/subsystem/atoms/proc/setupGenetics() var/list/mutations = subtypesof(/datum/mutation/human) shuffle_inplace(mutations) for(var/A in subtypesof(/datum/generecipe)) var/datum/generecipe/GR = A GLOB.mutation_recipes[initial(GR.required)] = initial(GR.result) for(var/i in 1 to LAZYLEN(mutations)) var/path = mutations[i] //byond gets pissy when we do it in one line var/datum/mutation/human/B = new path () B.alias = "Mutation [i]" GLOB.all_mutations[B.type] = B GLOB.full_sequences[B.type] = generate_gene_sequence(B.blocks) GLOB.alias_mutations[B.alias] = B.type if(B.locked) continue if(B.quality == POSITIVE) GLOB.good_mutations |= B else if(B.quality == NEGATIVE) GLOB.bad_mutations |= B else if(B.quality == MINOR_NEGATIVE) GLOB.not_good_mutations |= B CHECK_TICK /datum/controller/subsystem/atoms/proc/InitLog() . = "" for(var/path in BadInitializeCalls) . += "Path : [path] \n" var/fails = BadInitializeCalls[path] if(fails & BAD_INIT_DIDNT_INIT) . += "- Didn't call atom/Initialize()\n" if(fails & BAD_INIT_NO_HINT) . += "- Didn't return an Initialize hint\n" if(fails & BAD_INIT_QDEL_BEFORE) . += "- Qdel'd in New()\n" if(fails & BAD_INIT_SLEPT) . += "- Slept during Initialize()\n" /datum/controller/subsystem/atoms/Shutdown() var/initlog = InitLog() if(initlog) text2file(initlog, "[GLOB.log_directory]/initialize.log")