From cbc41f5d1309ee52e32d553fd3bd2ae6a2702695 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:09:51 +0100 Subject: [PATCH] [MIRROR] Fixes bug with atoms (including new players!!!!) not spawned from the holodeck being deleted by it if they happened to be initialized at the same time (#4260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes bug with atoms (including new players!!!!) not spawned from the holodeck being deleted by it if they happened to be initialized at the same time (#57510) About The Pull Request Fixes #57446 yeah not my best moment, holodeck currently sets SSatoms to add every call to InitAtom() to a list and then give it back to the holodeck console (it actually goes through map_template/holodeck to do it but whatever). However it turns out atom/New() calls InitAtom too, so if an atom is created while SSatoms is still creating the list to give to the holodeck then that atom is added to the list regardless of whether or not its actually from the holodeck template. Now theres an extra argument to InitAtom that tells it whether its spawned directly from a map template (ie, its part of the input list of uninitialized atoms that InitializeAtoms was given) or otherwise the output list that the holodeck uses is populated by calling GetAllContents on all atom/movables spawned directly from the template. also renamed some vars in initTemplateBounds because it was hard to reason what it was doing and made it use as anything also note that loading a map template with returns_created_atoms = TRUE will no longer track atoms that arent in the map file but are spawned directly onto a turf, currently nothing does this with the holodeck (which is the only map template that has this feature) by the way this bug is my fault Why It's Good For The Game incredibly incredibly unlucky new players dont deserve to be deleted just because they didnt spawn in the holodeck Changelog 🆑 fix: the holodeck is no longer so powerful that it can destroy anything and everything that dares to start existing while it's busy loading programs /🆑 * Fixes bug with atoms (including new players!!!!) not spawned from the holodeck being deleted by it if they happened to be initialized at the same time Co-authored-by: Kylerace --- code/__DEFINES/subsystems.dm | 2 +- code/controllers/subsystem/atoms.dm | 12 +++++------- code/game/atoms.dm | 2 +- code/modules/holodeck/computer.dm | 4 ---- code/modules/mapping/map_template.dm | 27 +++++++++++++-------------- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 8e43558a52e..74e245789fe 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -93,7 +93,7 @@ ..();\ if(!(flags_1 & INITIALIZED_1)) {\ args[1] = TRUE;\ - SSatoms.InitAtom(src, args);\ + SSatoms.InitAtom(src, FALSE, args);\ }\ } diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index 064e1d60885..dea5bcf101b 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -16,7 +16,6 @@ SUBSYSTEM_DEF(atoms) ///initAtom() adds the atom its creating to this list iff InitializeAtoms() has been given a list to populate as an argument var/list/created_atoms - // ^ if this is not null after InitializeAtoms() is done, this list will fill up with every atom in the world initialized afterwards! initialized = INITIALIZATION_INSSATOMS @@ -47,13 +46,13 @@ SUBSYSTEM_DEF(atoms) for(var/I in 1 to count) var/atom/A = atoms[I] if(!(A.flags_1 & INITIALIZED_1)) - InitAtom(A, mapload_arg) CHECK_TICK + InitAtom(A, TRUE, mapload_arg) else count = 0 for(var/atom/A in world) if(!(A.flags_1 & INITIALIZED_1)) - InitAtom(A, mapload_arg) + InitAtom(A, FALSE, mapload_arg) ++count CHECK_TICK @@ -74,7 +73,7 @@ SUBSYSTEM_DEF(atoms) created_atoms = null /// Init this specific atom -/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) +/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, from_template = FALSE, list/arguments) var/the_type = A.type if(QDELING(A)) BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE @@ -108,9 +107,8 @@ SUBSYSTEM_DEF(atoms) BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT else SEND_SIGNAL(A,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) - - if (created_atoms) - created_atoms += A + if(created_atoms && from_template && ispath(the_type, /atom/movable))//we only want to populate the list with movables + created_atoms += A.GetAllContents() return qdeleted || QDELING(A) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4bc3e33d18a..40552d16974 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -170,7 +170,7 @@ var/do_initialize = SSatoms.initialized if(do_initialize != INITIALIZATION_INSSATOMS) args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD - if(SSatoms.InitAtom(src, args)) + if(SSatoms.InitAtom(src, FALSE, args)) //we were deleted return diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index 72883b0d8aa..79deb5f1a4e 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -243,10 +243,6 @@ and clear when youre done! if you dont i will use :newspaper2: on you //turfs and overlay objects are taken out of the spawned list //objects get resistance flags added to them for (var/atom/atoms in spawned) - if (isturf(atoms) || istype(atoms, /obj/effect/overlay/vis)) - spawned -= atoms - continue - RegisterSignal(atoms, COMSIG_PARENT_PREQDELETED, .proc/remove_from_holo_lists) atoms.flags_1 |= HOLOGRAM_1 diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 83b5a590fff..1ac1b553cd7 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -43,7 +43,7 @@ var/list/obj/machinery/atmospherics/atmos_machines = list() var/list/obj/structure/cable/cables = list() - var/list/atom/atoms = list() + var/list/atom/movable/movables = list() var/list/area/areas = list() var/list/turfs = block( @@ -58,20 +58,19 @@ bounds[MAP_MAXZ] ) ) - for(var/L in turfs) - var/turf/B = L - var/area/G = B.loc - areas |= G + for(var/turf/current_turf as anything in turfs) + var/area/current_turfs_area = current_turf.loc + areas |= current_turfs_area if(!SSatoms.initialized) continue - for(var/A in B) - atoms += A - if(istype(A, /obj/structure/cable)) - cables += A + for(var/movable_in_turf in current_turf) + movables += movable_in_turf + if(istype(movable_in_turf, /obj/structure/cable)) + cables += movable_in_turf continue - if(istype(A, /obj/machinery/atmospherics)) - atmos_machines += A + if(istype(movable_in_turf, /obj/machinery/atmospherics)) + atmos_machines += movable_in_turf // Not sure if there is some importance here to make sure the area is in z // first or not. Its defined In Initialize yet its run first in templates @@ -81,7 +80,8 @@ if(!SSatoms.initialized) return - SSatoms.InitializeAtoms(areas + turfs + atoms, returns_created_atoms ? created_atoms : null) + SSatoms.InitializeAtoms(areas + turfs + movables, returns_created_atoms ? created_atoms : null) + // NOTE, now that Initialize and LateInitialize run correctly, do we really // need these two below? SSmachines.setup_template_powernets(cables) @@ -100,8 +100,7 @@ bounds[MAP_MAXZ] ) ) - for(var/t in template_and_bordering_turfs) - var/turf/affected_turf = t + for(var/turf/affected_turf as anything in template_and_bordering_turfs) affected_turf.air_update_turf(TRUE, TRUE) affected_turf.levelupdate()