From e1ce7b957228e375993493d1b226e5e0e67d2111 Mon Sep 17 00:00:00 2001 From: Aylong <69762909+AyIong@users.noreply.github.com> Date: Tue, 13 Aug 2024 04:24:49 +0300 Subject: [PATCH] Fix stack merge & return lost code (#26483) * Fix stack merge & return lost code * What is `S` and `O`? * Comment * Update code/game/objects/items/stacks/stack_recipe.dm Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> --------- Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> --- code/game/objects/items/stacks/stack.dm | 15 +++-- .../game/objects/items/stacks/stack_recipe.dm | 67 ++++++++++--------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 57a91e8fdaa..d7d42b57847 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -139,8 +139,9 @@ ui_interact(user) /obj/item/stack/attackby(obj/item/thing, mob/user, params) - if((parent_stack && !istype(thing, merge_type)) || !(parent_stack && thing.type == type)) - return ..() + if((parent_stack && !istype(thing, merge_type)) || (parent_stack && thing.type != type)) + ..() + return var/obj/item/stack/material = thing merge(material) @@ -215,9 +216,15 @@ var/datum/stack_recipe/recipe = locateUID(params["recipe_uid"]) var/multiplier = text2num(params["multiplier"]) if(!recipe.try_build(user, material, multiplier)) - return - return recipe.do_build(user, material, multiplier) + return FALSE + var/obj/result + result = recipe.do_build(user, material, multiplier, result) + if(!result) + return FALSE + + recipe.post_build(user, material, result) + return TRUE /** * Recursively builds the recipes data for the given list of recipes, iterating through each recipe. diff --git a/code/game/objects/items/stacks/stack_recipe.dm b/code/game/objects/items/stacks/stack_recipe.dm index 25b692c8250..a389993f0a1 100644 --- a/code/game/objects/items/stacks/stack_recipe.dm +++ b/code/game/objects/items/stacks/stack_recipe.dm @@ -63,26 +63,26 @@ src.image = "[icon2base64(result_icon)]" /// Returns TRUE if the recipe can be built, otherwise returns FALSE. This proc is only meant as a series of tests to check if construction is possible; the actual creation of the resulting atom should be handled in do_build() -/datum/stack_recipe/proc/try_build(mob/user, obj/item/stack/S, multiplier) - if(S.get_amount() < req_amount * multiplier) +/datum/stack_recipe/proc/try_build(mob/user, obj/item/stack/material, multiplier) + if(material.get_amount() < req_amount * multiplier) if(req_amount * multiplier > 1) - to_chat(user, "You haven't got enough [S] to build [res_amount * multiplier] [title]\s!") + to_chat(user, "You haven't got enough [material] to build [res_amount * multiplier] [title]\s!") else - to_chat(user, "You haven't got enough [S] to build [title]!") + to_chat(user, "You haven't got enough [material] to build [title]!") return FALSE - if(window_checks && !valid_window_location(get_turf(S), user.dir)) + if(window_checks && !valid_window_location(get_turf(material), user.dir)) to_chat(user, "[title] won't fit here!") return FALSE - if(one_per_turf && (locate(result_type) in get_turf(S))) + if(one_per_turf && (locate(result_type) in get_turf(material))) to_chat(user, "There is another [title] here!") return FALSE - if(on_floor && !issimulatedturf(get_turf(S))) + if(on_floor && !issimulatedturf(get_turf(material))) to_chat(user, "[title] must be constructed on the floor!") return FALSE - if(on_floor_or_lattice && !(issimulatedturf(get_turf(S)) || locate(/obj/structure/lattice) in get_turf(S))) + if(on_floor_or_lattice && !(issimulatedturf(get_turf(material)) || locate(/obj/structure/lattice) in get_turf(material))) to_chat(user, "[title] must be constructed on the floor or lattice!") return FALSE @@ -92,52 +92,53 @@ if(!is_level_reachable(user.z)) to_chat(user, "The energies of this place interfere with the metal shaping!") return FALSE - if(locate(/obj/structure/cult) in get_turf(S)) + if(locate(/obj/structure/cult) in get_turf(material)) to_chat(user, "There is a structure here!") return FALSE return TRUE /// Creates the atom defined by the recipe. Should always return the object it creates or FALSE. This proc assumes that the construction is already possible; for checking whether a recipe *can* be built before construction, use try_build() -/datum/stack_recipe/proc/do_build(mob/user, obj/item/stack/S, multiplier, atom/O) +/datum/stack_recipe/proc/do_build(mob/user, obj/item/stack/material, multiplier, atom/result) if(time) to_chat(user, "Building [title]...") - if(!do_after(user, time, target = S.loc)) + if(!do_after(user, time, target = material.loc)) return FALSE - if(cult_structure && locate(/obj/structure/cult) in get_turf(S)) //Check again after do_after to prevent queuing construction exploit. + if(cult_structure && locate(/obj/structure/cult) in get_turf(material)) // Check again after do_after to prevent queuing construction exploit. to_chat(user, "There is a structure here!") return FALSE - if(S.get_amount() < req_amount * multiplier) // Check they still have enough. + if(material.get_amount() < req_amount * multiplier) // Check they still have enough. return FALSE - if(max_res_amount > 1) //Is it a stack? - O = new result_type(get_turf(S), res_amount * multiplier) + if(max_res_amount > 1) // Is it a stack? + result = new result_type(get_turf(material), res_amount * multiplier) else - O = new result_type(get_turf(S)) - O.setDir(user.dir) - S.use(req_amount * multiplier) - S.updateUsrDialog() - return O + result = new result_type(get_turf(material)) -/// What should be done after the object is built? obj/item/stack/O might not actually be a stack, but this proc needs access to merge() to work, which is on obj/item/stack, so declare it as obj/item/stack anyways. -/datum/stack_recipe/proc/post_build(mob/user, obj/item/stack/S, obj/item/stack/O) - O.add_fingerprint(user) + result.setDir(user.dir) + result.update_icon(UPDATE_OVERLAYS) + material.use(req_amount * multiplier) + material.updateUsrDialog() + return result - if(isitem(O)) - if(isstack(O) && istype(O, user.get_inactive_hand())) - O.merge(user.get_inactive_hand()) - user.put_in_hands(O) +/// What should be done after the object is built? obj/item/stack/result might not actually be a stack, but this proc needs access to merge() to work, which is on obj/item/stack, so declare it as obj/item/stack anyways. +/datum/stack_recipe/proc/post_build(mob/user, obj/item/stack/material, obj/item/stack/result) + result.add_fingerprint(user) - //BubbleWrap - so newly formed boxes are empty - if(isstorage(O)) - for(var/obj/item/I in O) - qdel(I) - //BubbleWrap END + if(isitem(result)) + if(isstack(result) && istype(result, user.get_inactive_hand())) + result.merge(user.get_inactive_hand()) + user.put_in_hands(result) -/* Special Recipes */ + // BubbleWrap - so newly formed boxes are empty + if(isstorage(result)) + for(var/obj/item/thing in result) + qdel(thing) + // BubbleWrap END +// Special Recipes /datum/stack_recipe/cable_restraints /datum/stack_recipe/cable_restraints/post_build(mob/user, obj/item/stack/S, obj/result) if(istype(result, /obj/item/restraints/handcuffs/cable))