Adds new vending machine tooltips. (#81918)

## About The Pull Request

This PR adds tooltips to vending machines.
Specifically, the tooltips cover tool interactions (unwrench, toggle
panel open/closed, deconstruct), as well as righting a knocked over
vending machine with an open hand, and returning items to a vending
machine as applicable.

![image](https://github.com/tgstation/tgstation/assets/41715314/2af1eb6a-b357-423b-acd4-f9b6dd913b64)

![image](https://github.com/tgstation/tgstation/assets/41715314/816eb602-4831-41ea-a4b6-ece54cea4665)

![image](https://github.com/tgstation/tgstation/assets/41715314/f4ec55eb-b403-4444-9ae5-ea1978f7f578)

![image](https://github.com/tgstation/tgstation/assets/41715314/371c21b3-a884-4ec0-afa7-531f109c93b1)

![image](https://github.com/tgstation/tgstation/assets/41715314/fac5881e-89f0-482e-b19b-db0440684147)
This also provides a context for restock modules, which shows specific
text when the vending machine has credit to be claimed when restocked.

Tweaks a little bit of speech handling to prevent issues with
custom_vendor for determining if an item can be returned to re-use for
the tooltip proc.

## Why It's Good For The Game

Improves clarity on a high impact economy related piece of content, plus
we kinda *like* vending machines, based on how much code we have
dedicated to them. 🐛 💥

## Changelog

🆑
qol: Vending machines now have contextual tooltips for interactions with
tools/objects/restocking/returns.
qol: Vending machines can now be examined to see what type of restock
module they need to be refilled.
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>
This commit is contained in:
ArcaneMusic
2024-03-15 16:32:15 -06:00
committed by GitHub
co-authored by MrMelbert san7890
parent 7bbe7085a7
commit 1d2c8a83f6
+57 -6
View File
@@ -280,6 +280,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(onstation && !onstation_override)
AddComponent(/datum/component/payment, 0, SSeconomy.get_dep_account(payment_department), PAYMENT_VENDING)
GLOB.vending_machines_to_restock += src //We need to keep track of the final onstation vending machines so we can keep them restocked.
register_context()
/obj/machinery/vending/Destroy()
QDEL_NULL(wires)
@@ -342,6 +343,24 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(light_mask && !(machine_stat & BROKEN) && powered())
. += emissive_appearance(icon, light_mask, src)
/obj/machinery/vending/examine(mob/user)
. = ..()
if(isnull(refill_canister))
return // you can add the comment here instead
if((total_loaded_stock() / total_max_stock()) < 1)
. += span_notice("\The [src] can be restocked with [span_boldnotice("\a [refill_canister]")] with the panel open.")
else
. += span_notice("\The [src] is fully stocked.")
if(credits_contained < CREDITS_DUMP_THRESHOLD && credits_contained > 0)
. += span_notice("It should have a handfull of credits stored based on the missing items.")
else if (credits_contained > PAYCHECK_CREW)
. += span_notice("It should have at least a full paycheck worth of credits inside!")
/**
* Intentionally leaving out a case for zero credits as it should be covered by the vending machine's stock being full,
* or covered by first case if items were returned.
*/
/obj/machinery/vending/atom_break(damage_flag)
. = ..()
if(!.)
@@ -1101,6 +1120,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
vending_machine_input[inserted_item.type] = 1
loaded_items++
/obj/machinery/vending/unbuckle_mob(mob/living/buckled_mob, force = FALSE, can_fall = TRUE)
if(!force)
return
@@ -1578,11 +1598,13 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
* Arguments:
* * loaded_item - the item being loaded
* * user - the user doing the loading
* * send_message - should we send a message to the user if the item can't be loaded? Either a to_chat or a speak depending on vending type.
*/
/obj/machinery/vending/proc/canLoadItem(obj/item/loaded_item, mob/user)
/obj/machinery/vending/proc/canLoadItem(obj/item/loaded_item, mob/user, send_message = TRUE)
if(!length(loaded_item.contents) && ((loaded_item.type in products) || (loaded_item.type in premium) || (loaded_item.type in contraband)))
return TRUE
to_chat(user, span_warning("[src] does not accept [loaded_item]!"))
if(send_message)
to_chat(user, span_warning("[src] does not accept [loaded_item]!"))
return FALSE
/obj/machinery/vending/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
@@ -1611,6 +1633,32 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
credits_contained = max(0, credits_contained - credits_to_remove)
SSblackbox.record_feedback("amount", "vending machine looted", holochip.credits)
/obj/machinery/vending/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(tilted && !held_item)
context[SCREENTIP_CONTEXT_LMB] = "Right machine"
return CONTEXTUAL_SCREENTIP_SET
if(held_item?.tool_behaviour == TOOL_SCREWDRIVER)
context[SCREENTIP_CONTEXT_LMB] = panel_open ? "Close panel" : "Open panel"
return CONTEXTUAL_SCREENTIP_SET
if(panel_open && held_item?.tool_behaviour == TOOL_WRENCH)
context[SCREENTIP_CONTEXT_LMB] = anchored ? "Unsecure" : "Secure"
return CONTEXTUAL_SCREENTIP_SET
if(panel_open && held_item?.tool_behaviour == TOOL_CROWBAR)
context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
if(!isnull(held_item) && (vending_machine_input[held_item.type] || canLoadItem(held_item, user, send_message = FALSE)))
context[SCREENTIP_CONTEXT_LMB] = "Load item"
return CONTEXTUAL_SCREENTIP_SET
if(panel_open && istype(held_item, refill_canister))
context[SCREENTIP_CONTEXT_LMB] = "Restock vending machine[credits_contained ? " and collect credits" : null]"
return TRUE
return NONE
/obj/machinery/vending/custom
name = "Custom Vendor"
icon_state = "custom"
@@ -1636,16 +1684,19 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(id_card?.registered_account && id_card.registered_account == linked_account)
return TRUE
/obj/machinery/vending/custom/canLoadItem(obj/item/loaded_item, mob/user)
/obj/machinery/vending/custom/canLoadItem(obj/item/loaded_item, mob/user, send_message = TRUE)
. = FALSE
if(loaded_item.flags_1 & HOLOGRAM_1)
speak("This vendor cannot accept nonexistent items.")
if(send_message)
speak("This vendor cannot accept nonexistent items.")
return
if(loaded_items >= max_loaded_items)
speak("There are too many items in stock.")
if(send_message)
speak("There are too many items in stock.")
return
if(isstack(loaded_item))
speak("Loose items may cause problems, try to use it inside wrapping paper.")
if(send_message)
speak("Loose items may cause problems, try to use it inside wrapping paper.")
return
if(loaded_item.custom_price)
return TRUE