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))