diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index 33e4e1156c9b..0f3b2138bda3 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -137,7 +137,30 @@ SUBSYSTEM_DEF(atoms) /datum/controller/subsystem/atoms/proc/instance_atom_immediate(path, mapload, atom/where, ...) var/old_init_status = atom_init_status atom_init_status = mapload? ATOM_INIT_IN_NEW_MAPLOAD : ATOM_INIT_IN_NEW_REGULAR - var/atom/created = new path(arglist(args.Copy())) + var/atom/created = new path(arglist(args.Copy(3))) + atom_init_status = old_init_status + return created + +/** + * immediately creates and inits an atom with a preloader callback. + * + * @params + * * path - typepath + * * mapload - treat as mapload? + * * preload_call - callback to invoke with (created) for the created atom. This is not allowed to sleep. + * * where - location to init at + * * ... - rest of args are passed to new() / Initialize(). + */ +/datum/controller/subsystem/atoms/proc/instance_atom_immediate_with_preloader(path, mapload, datum/callback/preload_call, atom/where, ...) + var/old_init_status = atom_init_status + atom_init_status = ATOM_INIT_IN_SUBSYSTEM + var/atom/created = new path(arglist(args.Copy(4))) + preload_call.invoke_no_sleep(created) + atom_init_status = mapload? ATOM_INIT_IN_NEW_MAPLOAD : ATOM_INIT_IN_NEW_REGULAR + // this sets 'where' to if we should be mapload. + // this is acceptable because args[4] ('where') is not used again. + args[4] = mapload + InitAtom(created, FALSE, args) atom_init_status = old_init_status return created diff --git a/code/datums/recipe/stack_recipe.dm b/code/datums/recipe/stack_recipe.dm index 4f453f0e68d0..6eee81b75cd4 100644 --- a/code/datums/recipe/stack_recipe.dm +++ b/code/datums/recipe/stack_recipe.dm @@ -52,6 +52,17 @@ var/on_border = FALSE // todo: material constraints + //* Product Descriptors *// + + /// Automatically create empty storage / cells / containers / whatever + /// * Usually this is on, because usually stacks are not meant to create the insides of a container. + var/product_auto_create_empty = TRUE + + //* Internal *// + + /// preloader callback, do not touch + var/datum/callback/preloader_callback + /datum/stack_recipe/New() if(ispath(result_type, /obj/item/stack)) result_is_stack = TRUE @@ -59,6 +70,12 @@ var/atom/casted = result_type on_border = !!(initial(casted.atom_flags) & ATOM_BORDER) + preloader_callback = CALLBACK(src, make_preload_hook) + +/datum/stack_recipe/Destroy() + QDEL_NULL(preloader_callback) + return ..() + /** * attepmt to craft * @@ -131,6 +148,7 @@ * * creating - (optional) list will be populated of objects created. supply a list so you can read it, or don't to ignore. */ /datum/stack_recipe/proc/make(atom/where, amount, obj/item/stack/stack, mob/user, silent, use_dir, list/created = list()) + #warn preload call for making sure stacks get made empty if(result_is_stack) var/obj/item/stack/casted = result_type var/max_amount = initial(casted.max_amount) @@ -139,16 +157,22 @@ if(!--safety) CRASH("safety hit") var/making_amount = min(amount, max_amount) - var/obj/item/stack/creating = new result_type(where, making_amount) + var/obj/item/stack/creating = Ssatoms.instance_atom_immediate_with_preloader(result_type, FALSE, preloader_callback, where, making_amount) amount -= making_amount created += creating else for(var/i in 1 to min(amount, 50)) - var/atom/movable/creating = new result_type(where) + var/atom/movable/creating = Ssatoms.instance_atom_immediate_with_preloader(result_type, FALSE, preloader_callback, where) creating.setDir(use_dir) created += creating return TRUE +/** + * preloads an atom we make + */ +/datum/stack_recipe/proc/make_preload_hook(atom/product) + product.preload_from_stack_recipe(src) + /** * tgui stack recipe data */ diff --git a/code/game/atoms/_atom.dm b/code/game/atoms/_atom.dm index e0d07548e9e3..51d5ddf4d557 100644 --- a/code/game/atoms/_atom.dm +++ b/code/game/atoms/_atom.dm @@ -234,6 +234,8 @@ /** * Called by the maploader if a dmm_context is set + * + * todo: rename to preload_from_mapload() */ /atom/proc/preloading_instance(datum/dmm_context/context) return @@ -241,6 +243,8 @@ /** * hook for abstract direction sets from the maploader * + * todo: this might need to be part of preloading_instance; investigate + * * return FALSE to override maploader automatic rotation */ /atom/proc/preloading_dir(datum/dmm_context/context) diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index ab6f5c2c6c7a..bb36b731acc6 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -42,6 +42,7 @@ var/storage_datum_path = /datum/object_system/storage /// Cleared after Initialize(). /// List of types associated to amounts. + // todo: stack handling var/list/starts_with /// set to prevent us from spawning starts_with var/empty = FALSE @@ -49,7 +50,7 @@ /obj/item/storage/Initialize(mapload, empty) . = ..() initialize_storage() - if(!empty) + if(!empty || src.empty) spawn_contents() legacy_spawn_contents() else @@ -59,7 +60,7 @@ * Make sure to set [worth_dynamic] to TRUE if this does more than spawning what's in starts_with. */ /obj/item/storage/proc/spawn_contents() - if(length(starts_with) && !empty) + if(length(starts_with)) // this is way too permissive already var/safety = 256 var/atom/where_real_contents = obj_storage.real_contents_loc()