From b876efd54b8be4ff5aa278f20ffa2e98c0f596d3 Mon Sep 17 00:00:00 2001
From: Bloop <13398309+vinylspiders@users.noreply.github.com>
Date: Sat, 23 Dec 2023 04:59:07 -0500
Subject: [PATCH] Fixes duplicating space beer (#80500)
## About The Pull Request
Fixes https://github.com/Skyrat-SS13/Skyrat-tg/issues/25760
Fixes https://github.com/tgstation/tgstation/issues/80271
I don't know if it was a result of the react port or not (likely it
was), but unexpected behavior occurs when multiple objects are mapped to
the same key.
In this case, there were two items named 'Space Beer', so in order to
have unique keys I've changed it so that they're keyed to the path
instead of the name.
Shown below, the two types of beer:

Beer duplicating when switching tabs

No more of that

edit: also fixes a bug where buying an item with the same name as
another would decrement the stock of both items.
Fixed (see space beer)

## Why It's Good For The Game
Fixes a bug
## Changelog
:cl:
fix: the boozeomat ui will stop duplicating space beer bottles
refactor: refactored vending machine backend to have unique keys for
their data structures. should fix bugs related to items that happen to
have the same name.
/:cl:
---
code/modules/vending/_vending.dm | 26 ++++++++++++-----------
tgui/packages/tgui/interfaces/Vending.tsx | 9 ++++----
2 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index 37179dd36f4..f3f7e9c355c 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -1039,10 +1039,10 @@
LAZYADD(product_datum.returned_products, inserted_item)
return
- if(vending_machine_input[format_text(inserted_item.name)])
- vending_machine_input[format_text(inserted_item.name)]++
+ if(vending_machine_input[inserted_item.type])
+ vending_machine_input[inserted_item.type]++
else
- vending_machine_input[format_text(inserted_item.name)] = 1
+ vending_machine_input[inserted_item.type] = 1
loaded_items++
/obj/machinery/vending/unbuckle_mob(mob/living/buckled_mob, force = FALSE, can_fall = TRUE)
@@ -1210,7 +1210,7 @@
colorable = product_record.colorable,
)
- .["stock"][product_record.name] = product_data
+ .["stock"] += list(product_data)
.["extended_inventory"] = extended_inventory
@@ -1599,12 +1599,12 @@
. = ..()
.["access"] = compartmentLoadAccessCheck(user)
.["vending_machine_input"] = list()
- for (var/stocked_item in vending_machine_input)
+ for (var/obj/item/stocked_item as anything in vending_machine_input)
if(vending_machine_input[stocked_item] > 0)
var/base64
var/price = 0
for(var/obj/item/stored_item in contents)
- if(format_text(stored_item.name) == stocked_item)
+ if(stored_item.type == stocked_item)
price = stored_item.custom_price
if(!base64) //generate an icon of the item to use in UI
if(base64_cache[stored_item.type])
@@ -1614,7 +1614,8 @@
base64_cache[stored_item.type] = base64
break
var/list/data = list(
- name = stocked_item,
+ path = stocked_item,
+ name = initial(stocked_item.name),
price = price,
img = base64,
amount = vending_machine_input[stocked_item],
@@ -1629,8 +1630,8 @@
switch(action)
if("dispense")
if(isliving(usr))
- vend_act(usr, params["item"])
- vend_ready = TRUE
+ vend_act(usr, params)
+ vend_ready = TRUE
return TRUE
/obj/machinery/vending/custom/attackby(obj/item/attack_item, mob/user, params)
@@ -1668,9 +1669,10 @@
* Updating stock, account transactions, alerting users.
* @return -- TRUE if a valid condition was met, FALSE otherwise.
*/
-/obj/machinery/vending/custom/proc/vend_act(mob/living/user, choice)
+/obj/machinery/vending/custom/proc/vend_act(mob/living/user, list/params)
if(!vend_ready)
return
+ var/obj/item/choice = text2path(params["item"]) // typepath is a string coming from javascript, we need to convert it back
var/obj/item/dispensed_item
var/obj/item/card/id/id_card = user.get_idcard(TRUE)
vend_ready = FALSE
@@ -1679,8 +1681,8 @@
flick(icon_deny, src)
return TRUE
var/datum/bank_account/payee = id_card.registered_account
- for(var/obj/stock in contents)
- if(format_text(stock.name) == choice)
+ for(var/obj/item/stock in contents)
+ if(istype(stock, choice))
dispensed_item = stock
break
if(!dispensed_item)
diff --git a/tgui/packages/tgui/interfaces/Vending.tsx b/tgui/packages/tgui/interfaces/Vending.tsx
index 942e0680290..0311f3555a1 100644
--- a/tgui/packages/tgui/interfaces/Vending.tsx
+++ b/tgui/packages/tgui/interfaces/Vending.tsx
@@ -65,6 +65,7 @@ type StockItem = {
};
type CustomInput = {
+ path: string;
name: string;
price: number;
img: string;
@@ -217,12 +218,12 @@ const ProductDisplay = (props: {
return true;
}
})
- .map((product) => (
+ .map((product, index) => (
))}
@@ -350,7 +351,7 @@ const ProductButton = (props) => {
disabled={disabled}
onClick={() =>
act('dispense', {
- item: product.name,
+ item: product.path,
})
}
>