Files
MrMelbert 7b8eb2c7c7 Intelligent vendors may deny usage if you are poor (or outright if they are active/moving) (#95311)
## About The Pull Request

When brand intelligence triggers, infected vending machines have a 50%
chance to deny you from using them unless you are moderately wealthy
(>=1000 cr)

When the vending machines activate/start moving, they outright deny
usage from everyone

## Why It's Good For The Game

We have some very good vendor deny icons but they are almost completely
impossible to trigger in game (with the exception of booze vendors and
some very edge cases)

Someone gave me the idea to use them in the brand intelligence event and
it feels pretty appropriate. Also helps you identify infected vendors
(whereas right now you can only tell by the occasional message). Maybe
it'll even incentivize people to actually hunt down the origin rather
than just wait it out.

## Changelog

🆑 Melbert
add: Intelligence vendors (from the event) have a 50% chance to deny
users who are not wealthy. When the vendors awake and start moving, they
instead get a 100% chance to deny anyone.
/🆑
2026-03-19 05:25:39 +00:00

185 lines
5.9 KiB
Plaintext

///Helper to create a typepath to be used in the UI
#define SANITIZED_PATH(path)(replacetext(replacetext("[path]", "/obj/item/", ""), "/", "-"))
/obj/machinery/vending/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet_batched/vending),
)
/obj/machinery/vending/ui_interact(mob/user, datum/tgui/ui)
if(SEND_SIGNAL(src, COMSIG_VENDING_UI_INTERACT, user, ui) & VENDING_DENIED)
if(icon_deny)
flick(icon_deny, src)
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Vending", name)
ui.open()
/**
* Returns a list of given product records of the vendor to be used in UI.
* arguments:
* records - list of records available
* categories - list of categories available
* premium - bool of whether a record should be priced by a custom/premium price or not
*/
/obj/machinery/vending/proc/collect_records_for_static_data(list/records, list/categories, premium)
PROTECTED_PROC(TRUE)
var/static/list/default_category = list(
"name" = "Products",
"icon" = "cart-shopping",
)
var/list/out_records = list()
for (var/datum/data/vending_product/record as anything in records)
var/list/static_record = list(
path = SANITIZED_PATH(record.product_path),
name = record.name,
price = record.price,
ref = REF(record),
colorable = record.colorable,
)
var/atom/printed = record.product_path
// If it's not GAGS and has no innate colors we have to care about, we use DMIcon
if(ispath(printed, /atom) \
&& (!initial(printed.greyscale_config) || !initial(printed.greyscale_colors)) \
&& !initial(printed.color) \
)
static_record["icon"] = initial(printed.icon)
static_record["icon_state"] = initial(printed.icon_state)
var/list/category = record.category || default_category
if (!isnull(category))
if (!(category["name"] in categories))
categories[category["name"]] = list("icon" = category["icon"])
static_record["category"] = category["name"]
if (premium)
static_record["premium"] = TRUE
out_records += list(static_record)
return out_records
/obj/machinery/vending/ui_static_data(mob/user)
var/list/data = list()
if(ad_list.len)
data["ad"] = ad_list[rand(1, ad_list.len)]
data["all_products_free"] = all_products_free
data["department"] = payment_department
data["jobDiscount"] = DEPARTMENT_DISCOUNT
data["product_records"] = list()
data["displayed_currency_icon"] = displayed_currency_icon
data["displayed_currency_name"] = " [displayed_currency_name]"
var/list/categories = list()
data["product_records"] = collect_records_for_static_data(product_records, categories)
data["coin_records"] = collect_records_for_static_data(coin_records, categories, premium = TRUE)
data["hidden_records"] = collect_records_for_static_data(hidden_records, categories, premium = TRUE)
data["categories"] = categories
return data
/**
* Returns the balance that the vendor will use for proceeding payment. Most vendors would want to use the user's
* card's account credits balance.
* arguments:
* passed_id - the id card that will be billed for the product
*/
/obj/machinery/vending/proc/fetch_balance_to_use(obj/item/card/id/passed_id)
PROTECTED_PROC(TRUE)
return passed_id.registered_account.account_balance
/obj/machinery/vending/ui_data(mob/user)
. = list()
var/obj/item/card/id/card_used
var/held_cash = 0
if(isliving(user))
var/mob/living/living_user = user
card_used = living_user.get_idcard(TRUE)
held_cash = living_user.tally_physical_credits()
var/list/user_data = null
if(card_used?.registered_account)
user_data = list()
user_data["name"] = card_used.registered_account.account_holder
user_data["cash"] = fetch_balance_to_use(card_used) + held_cash
if(card_used.registered_account.account_job)
user_data["job"] = card_used.registered_account.account_job.title
user_data["department"] = card_used.registered_account.account_job.paycheck_department
else
user_data["job"] = "No Job"
user_data["department"] = DEPARTMENT_UNASSIGNED
.["user"] = user_data
.["stock"] = list()
for (var/datum/data/vending_product/product_record as anything in product_records + coin_records + hidden_records)
.["stock"][SANITIZED_PATH(product_record.product_path)] = list(
amount = product_record.amount,
free = length(product_record.returned_products)
)
if(prob(10) && ad_list.len)
.["ad"] = ad_list[rand(1, ad_list.len)]
.["extended_inventory"] = extended_inventory
/obj/machinery/vending/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("vend")
. = vend(params, ui.user)
if("select_colors")
var/datum/data/vending_product/product = locate(params["ref"])
if(!istype(product))
return FALSE
var/atom/fake_atom = product.product_path
var/config = initial(fake_atom.greyscale_config)
if(!config)
return FALSE
var/list/allowed_configs = list("[config]")
if(ispath(fake_atom, /obj/item))
var/obj/item/item = fake_atom
if(initial(item.greyscale_config_worn))
allowed_configs += "[initial(item.greyscale_config_worn)]"
if(initial(item.greyscale_config_inhand_left))
allowed_configs += "[initial(item.greyscale_config_inhand_left)]"
if(initial(item.greyscale_config_inhand_right))
allowed_configs += "[initial(item.greyscale_config_inhand_right)]"
var/datum/greyscale_modify_menu/menu = new(
src, ui.user, allowed_configs, CALLBACK(src, PROC_REF(_vend_greyscale), params, ui.user),
starting_icon_state=initial(fake_atom.icon_state),
starting_config = initial(fake_atom.greyscale_config),
starting_colors = initial(fake_atom.greyscale_colors)
)
menu.ui_interact(ui.user)
return TRUE
/**
* Vends a greyscale modified item.
* arguments:
* menu - greyscale config menu that has been used to vend the item
*/
/obj/machinery/vending/proc/_vend_greyscale(list/params, mob/user, datum/greyscale_modify_menu/menu)
PRIVATE_PROC(TRUE)
if(user != menu.user)
return
vend(params, user, menu.split_colors)
#undef SANITIZED_PATH