Files
Bubberstation/code/controllers/subsystem/atoms.dm
SkyratBot bd75f38fd6 [MIRROR] Initialize and LateInitialize runs correctly at round start (#1478)
* Initialize and LateInitialize runs correctly at round start (#54594)

I've been pulling my hair out on this one. Ever since I started my ntnet project, I could never get LateInitalize to work right. Apparently it has never worked right. How it was set up before on server start

    Station map loads, Does NOT run Initialize(mapload = TRUE)
    Generates space, lavaland/icebox ruins
    Loads a ruin, DOES run Initialize(mapload = TRUE) EXCEPT on areas
    End of mapping system
    Atom system Initialized and it checks and runs Initialize(mapload = TRUE) on world

You see the issue? Initialize and by extension LateInitialize is run in blocks. Worst, LateInitialize is run on turfs FIRST in ruins BEFORE Initialize is ever run on the other atoms. While there isn't much in Area, there is map_generator so I am sure it caused some grief for map creators.

The NEW order now is

    Station map loads, Does NOT run Initialize(mapload = TRUE)
    Generates space, lavaland/icebox ruins
    Loads a ruin, Does NOT run Initialize(mapload = TRUE)
    End of mapping system
    Atom system Initialized and it checks and runs Initialize(mapload = TRUE) on world

Also if you dynamicly load a map, like snowdin or such, it will Initialize all atoms at once and then run LateInitialize properly

* Initialize and LateInitialize runs correctly at round start

Co-authored-by: WarlockD <warlockd@gmail.com>
2020-10-27 02:22:25 +00:00

162 lines
4.2 KiB
Plaintext

#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 atoms)
var/atom/A = I
if(!(A.flags_1 & INITIALIZED_1))
InitAtom(I, 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 late_loaders)
var/atom/A = 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")
#undef BAD_INIT_QDEL_BEFORE
#undef BAD_INIT_DIDNT_INIT
#undef BAD_INIT_SLEPT
#undef BAD_INIT_NO_HINT