mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
VueUI Vending Machines III: Revenge of the Spritesheets (#10311)
It's #10197 and #10240 again, except this time using spritesheets from #10272. Also fixes issues with coin interactions / premium items, and some other minor tweaks.
This commit is contained in:
@@ -769,12 +769,16 @@ proc/ColorTone(rgb, tone)
|
||||
var/list/flat_size = list(1, flat.Width(), 1, flat.Height())
|
||||
// Dimensions of overlay being added
|
||||
var/list/add_size[4]
|
||||
var/blend_color = A.color ? TRUE : FALSE
|
||||
|
||||
for(var/V in layers)
|
||||
var/image/I = V
|
||||
if(I.alpha == 0)
|
||||
continue
|
||||
|
||||
if(blend_color && I.appearance_flags == RESET_COLOR)
|
||||
blend_color = FALSE
|
||||
|
||||
if(I == copy) // 'I' is an /image based on the object being flattened.
|
||||
curblend = BLEND_OVERLAY
|
||||
add = icon(I.icon, I.icon_state, base_icon_dir)
|
||||
@@ -803,7 +807,7 @@ proc/ColorTone(rgb, tone)
|
||||
// Blend the overlay into the flattened icon
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
|
||||
|
||||
if(A.color)
|
||||
if(A.color && blend_color)
|
||||
if(islist(A.color))
|
||||
flat.MapColors(arglist(A.color))
|
||||
else
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
for(var/type in typesof(/datum/asset))
|
||||
var/datum/asset/A = type
|
||||
if (type != initial(A._abstract))
|
||||
if (type != initial(A._abstract) && !initial(A.delayed))
|
||||
get_asset_datum(type)
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
@@ -9,22 +9,32 @@
|
||||
var/price = 0 // Price to buy one
|
||||
var/display_color = null // Display color for vending machine listing
|
||||
var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium
|
||||
var/icon/product_icon
|
||||
var/icon/icon_state
|
||||
|
||||
/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL)
|
||||
..()
|
||||
|
||||
src.product_path = path
|
||||
product_path = path
|
||||
var/atom/A = new path(null)
|
||||
|
||||
if(!name)
|
||||
var/atom/tmp = path
|
||||
src.product_name = initial(tmp.name)
|
||||
product_name = initial(A.name)
|
||||
else
|
||||
src.product_name = name
|
||||
product_name = name
|
||||
|
||||
src.amount = amount
|
||||
src.price = price
|
||||
src.display_color = color
|
||||
src.category = category
|
||||
if(istype(A, /obj/item/seeds))
|
||||
// thanks seeds for being overlays defined at runtime
|
||||
var/obj/item/seeds/S = A
|
||||
product_icon = S.update_appearance(TRUE)
|
||||
else
|
||||
product_icon = new /icon(A.icon, A.icon_state)
|
||||
icon_state = product_icon
|
||||
QDEL_NULL(A)
|
||||
|
||||
/**
|
||||
* A vending machine
|
||||
@@ -51,6 +61,7 @@
|
||||
var/active = 1 //No sales pitches if off!
|
||||
var/vend_ready = 1 //Are we ready to vend?? Is it time??
|
||||
var/vend_delay = 10 //How long does it take to vend?
|
||||
var/vending = FALSE
|
||||
|
||||
var/categories = CAT_NORMAL // Bitmask of cats we're currently showing
|
||||
var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now
|
||||
@@ -99,6 +110,7 @@
|
||||
var/restock_items = 0 //If items can be restocked into the vending machine
|
||||
var/list/restock_blocked_items = list() //Items that can not be restocked if restock_items is enabled
|
||||
var/random_itemcount = 1 //If the number of items should be randomized
|
||||
var/sel_key = 0
|
||||
|
||||
var/temperature_setting = 0 //-1 means cooling, 1 means heating, 0 means doing nothing.
|
||||
|
||||
@@ -110,10 +122,13 @@
|
||||
var/global/list/screen_overlays
|
||||
var/exclusive_screen = TRUE // Are we not allowed to show the deny and screen states at the same time?
|
||||
|
||||
var/ui_size = 80 // this is for scaling the ui buttons - i've settled on 80x80 for machines with prices, and 60x60 for those without and with large inventories (boozeomat)
|
||||
var/datum/asset/spritesheet/vending/v_asset
|
||||
|
||||
light_range = 2
|
||||
light_power = 1
|
||||
|
||||
/obj/machinery/vending/Initialize()
|
||||
/obj/machinery/vending/Initialize(mapload)
|
||||
. = ..()
|
||||
wires = new(src)
|
||||
if(src.product_slogans)
|
||||
@@ -132,6 +147,14 @@
|
||||
src.build_inventory()
|
||||
power_change()
|
||||
|
||||
if(mapload)
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/vending/LateInitialize()
|
||||
var/path = "/datum/asset/spritesheet/vending/"
|
||||
path = path + ckey(replacetext("[type]", "/obj/machinery/vending/", ""))
|
||||
v_asset = get_asset_datum(text2path(path))
|
||||
|
||||
/obj/machinery/vending/proc/reset_light()
|
||||
set_light(initial(light_range), initial(light_power), initial(light_color))
|
||||
|
||||
@@ -252,10 +275,11 @@
|
||||
handled = 1
|
||||
|
||||
if(paid)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
src.vend(currently_vending, usr)
|
||||
return
|
||||
else if(handled)
|
||||
SSnanoui.update_uis(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
return // don't smack that machine with your 2 credits
|
||||
|
||||
if (I || istype(W, /obj/item/spacecash))
|
||||
@@ -268,7 +292,6 @@
|
||||
add_screen_overlay()
|
||||
if(src.panel_open)
|
||||
add_overlay("[initial(icon_state)]-panel")
|
||||
SSnanoui.update_uis(src) // Speaker switch is on the main UI, not wires UI
|
||||
return
|
||||
else if(W.ismultitool()||W.iswirecutter())
|
||||
if(src.panel_open)
|
||||
@@ -279,7 +302,7 @@
|
||||
coin = W
|
||||
categories |= CAT_COIN
|
||||
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
return
|
||||
else if(W.iswrench())
|
||||
if(!can_move)
|
||||
@@ -491,46 +514,73 @@
|
||||
if(src.shock(user, 100))
|
||||
return
|
||||
|
||||
if (panel_open)
|
||||
wires.Interact(user)
|
||||
else
|
||||
ui_interact(user)
|
||||
|
||||
/**
|
||||
* Display the NanoUI window for the vending machine.
|
||||
*
|
||||
* See NanoUI documentation for details.
|
||||
*/
|
||||
/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
// VueUI implementation of vending machines.
|
||||
/obj/machinery/vending/ui_interact(mob/user, var/datum/topic_state/state = default_state)
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
var/list/data = list()
|
||||
if(currently_vending)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if(!ui)
|
||||
ui = new(user, src, "machinery-vending", 425, 500, capitalize(name), state=state)
|
||||
|
||||
ui.open(v_asset)
|
||||
|
||||
/obj/machinery/vending/vueui_data_change(list/data, mob/user, datum/vueui/ui)
|
||||
LAZYINITLIST(data)
|
||||
LAZYINITLIST(data["products"])
|
||||
|
||||
VUEUI_SET_CHECK_IFNOTSET(data["ui_size"], ui_size, ., data)
|
||||
|
||||
if(currently_vending || !vend_ready)
|
||||
data["mode"] = 1
|
||||
data["product"] = currently_vending.product_name
|
||||
data["price"] = currently_vending.price
|
||||
data["message_err"] = 0
|
||||
data["sel_key"] = sel_key
|
||||
data["sel_name"] = capitalize_first_letters(strip_improper(currently_vending.product_name))
|
||||
data["sel_price"] = currently_vending.price
|
||||
data["sel_icon"] = v_asset.icon_tag(ckey("[currently_vending.product_path]"), FALSE)
|
||||
data["message"] = src.status_message
|
||||
data["message_err"] = src.status_error
|
||||
else
|
||||
data["mode"] = 0
|
||||
var/list/listed_products = list()
|
||||
data["sel_key"] = 0
|
||||
data["sel_name"] = 0
|
||||
data["sel_price"] = 0
|
||||
data["sel_icon"] = 0
|
||||
data["message"] = ""
|
||||
data["message_err"] = 0
|
||||
|
||||
for(var/key = 1 to src.product_records.len)
|
||||
var/datum/data/vending_product/I = src.product_records[key]
|
||||
if(!(LAZYLEN(data["products"])) || LAZYLEN(data["products"]) != LAZYLEN(product_records))
|
||||
data["products"] = list()
|
||||
for(var/key = 1 to LAZYLEN(product_records))
|
||||
var/t_key = num2text(key)
|
||||
var/datum/data/vending_product/I = product_records[key]
|
||||
|
||||
if(!(I.category & src.categories))
|
||||
if(!(I.category & categories))
|
||||
continue
|
||||
|
||||
listed_products.Add(list(list(
|
||||
"key" = key,
|
||||
"name" = I.product_name,
|
||||
"price" = I.price,
|
||||
"color" = I.display_color,
|
||||
"amount" = I.amount)))
|
||||
var/product_name = capitalize_first_letters(strip_improper(I.product_name))
|
||||
var/icon_tag = v_asset.icon_tag(ckey("[I.product_path]"), FALSE)
|
||||
|
||||
data["products"] = listed_products
|
||||
LAZYINITLIST(data["products"][t_key])
|
||||
|
||||
if(src.coin)
|
||||
data["coin"] = src.coin.name
|
||||
VUEUI_SET_CHECK(data["products"][t_key]["key"], t_key, ., data)
|
||||
VUEUI_SET_CHECK(data["products"][t_key]["name"], product_name, ., data)
|
||||
VUEUI_SET_CHECK(data["products"][t_key]["price"], I.price, ., data)
|
||||
VUEUI_SET_CHECK(data["products"][t_key]["amount"], I.amount, ., data)
|
||||
VUEUI_SET_CHECK(data["products"][t_key]["icon_tag"], icon_tag, ., data)
|
||||
|
||||
else if(sel_key && product_records[text2num(sel_key)])
|
||||
var/datum/data/vending_product/V = product_records[text2num(sel_key)]
|
||||
VUEUI_SET_CHECK(data["products"][sel_key]["amount"], V.amount, ., data)
|
||||
|
||||
if(coin)
|
||||
data["coin"] = coin.name
|
||||
else
|
||||
data["coin"] = null
|
||||
|
||||
if(src.panel_open)
|
||||
data["panel"] = 1
|
||||
@@ -538,13 +588,10 @@
|
||||
else
|
||||
data["panel"] = 0
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
return data
|
||||
|
||||
/obj/machinery/vending/Topic(href, href_list)
|
||||
|
||||
var/datum/money_account/vendor_account = SSeconomy.get_department_account("Vendor")
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
@@ -576,6 +623,7 @@
|
||||
return
|
||||
|
||||
var/key = text2num(href_list["vendItem"])
|
||||
sel_key = href_list["vendItem"]
|
||||
var/datum/data/vending_product/R = product_records[key]
|
||||
|
||||
// This should not happen unless the request from NanoUI was bad
|
||||
@@ -583,6 +631,7 @@
|
||||
return
|
||||
|
||||
if(R.price <= 0)
|
||||
src.currently_vending = R
|
||||
src.vend(R, usr)
|
||||
else if(istype(usr,/mob/living/silicon)) //If the item is not free, provide feedback if a synth is trying to buy something.
|
||||
to_chat(usr, "<span class='danger'>Artificial unit recognized. Artificial units cannot complete this transaction. Purchase canceled.</span>")
|
||||
@@ -599,13 +648,19 @@
|
||||
else if (href_list["cancelpurchase"])
|
||||
src.currently_vending = null
|
||||
|
||||
else if (href_list["reset"])
|
||||
// reset button that nobody should ever (hopefully) see
|
||||
src.currently_vending = null
|
||||
src.vend_ready = 1
|
||||
|
||||
else if ((href_list["togglevoice"]) && (src.panel_open))
|
||||
src.shut_up = !src.shut_up
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
SSnanoui.update_uis(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
|
||||
|
||||
if (!R || R.amount < 1)
|
||||
return
|
||||
|
||||
@@ -622,32 +677,33 @@
|
||||
src.vend_ready = 0 //One thing at a time!!
|
||||
src.status_message = "Vending..."
|
||||
src.status_error = 0
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
if (R.category & CAT_COIN)
|
||||
if(!coin)
|
||||
to_chat(user, "<span class='notice'>You need to insert a coin to get this item.</span>")
|
||||
to_chat(user, SPAN_NOTICE("You need a coin to vend this item."))
|
||||
return
|
||||
|
||||
if(coin.string_attached)
|
||||
if(prob(50))
|
||||
to_chat(user, "<span class='notice'>You successfully pull the coin out before \the [src] could swallow it.</span>")
|
||||
src.visible_message("<span class='notice'>The [src] putters to life, coughing out its 'premium' item after a moment.</span>")
|
||||
playsound(src.loc, 'sound/items/poster_being_created.ogg', 50, 1)
|
||||
to_chat(user, SPAN_NOTICE("You successfully pull the coin out before \the [src] could swallow it!"))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You weren't able to pull the coin out fast enough, the machine ate it, string and all.</span>")
|
||||
src.visible_message("<span class='notice'>The [src] putters to life, coughing out its 'premium' item after a moment.</span>")
|
||||
playsound(src.loc, 'sound/items/poster_being_created.ogg', 50, 1)
|
||||
qdel(coin)
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
to_chat(user, SPAN_WARNING("You weren't able to pull the coin out fast enough, and the machine ate it!"))
|
||||
QDEL_NULL(coin)
|
||||
else
|
||||
src.visible_message("<span class='notice'>The [src] putters to life, coughing out its 'premium' item after a moment.</span>")
|
||||
playsound(src.loc, 'sound/items/poster_being_created.ogg', 50, 1)
|
||||
qdel(coin)
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
QDEL_NULL(coin)
|
||||
|
||||
visible_message(SPAN_NOTICE("\The [src] putters to life, coughing out its 'premium' item after a moment."))
|
||||
playsound(loc, 'sound/items/poster_being_created.ogg', 50, 1)
|
||||
|
||||
R.amount--
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
if(!coin)
|
||||
categories &= ~CAT_COIN
|
||||
|
||||
else
|
||||
R.amount--
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply)
|
||||
spawn(0)
|
||||
@@ -661,6 +717,7 @@
|
||||
addtimer(CALLBACK(src, .proc/vend_product, R, user), vend_delay)
|
||||
|
||||
/obj/machinery/vending/proc/vend_product(var/datum/data/vending_product/R, mob/user)
|
||||
|
||||
var/vending_usr_dir = get_dir(src, user)
|
||||
var/obj/vended = new R.product_path(get_step(src, vending_usr_dir))
|
||||
if(Adjacent(user))
|
||||
@@ -669,7 +726,7 @@
|
||||
src.status_error = 0
|
||||
src.vend_ready = 1
|
||||
currently_vending = null
|
||||
SSnanoui.update_uis(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
if(istype(vended,/obj/item/reagent_containers/))
|
||||
var/obj/item/reagent_containers/RC = vended
|
||||
if(RC.reagents)
|
||||
@@ -680,10 +737,11 @@
|
||||
use_power(RC.reagents.set_temperature(heating_temperature))
|
||||
|
||||
/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
|
||||
|
||||
to_chat(user, "<span class='notice'>You insert \the [R.product_name] in the product receptor.</span>")
|
||||
R.amount++
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
/obj/machinery/vending/machinery_process()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
@@ -743,6 +801,7 @@
|
||||
while(R.amount>0)
|
||||
new dump_path(get_random_turf_in_range(src, 1, 1, TRUE))
|
||||
R.amount--
|
||||
SSvueui.check_uis_for_change(src)
|
||||
break
|
||||
|
||||
stat |= BROKEN
|
||||
@@ -764,6 +823,7 @@
|
||||
continue
|
||||
|
||||
R.amount--
|
||||
SSvueui.check_uis_for_change(src)
|
||||
throw_item = new dump_path(src.loc)
|
||||
break
|
||||
if (!throw_item)
|
||||
|
||||
@@ -122,7 +122,18 @@
|
||||
vending_sound = 'sound/machines/vending/vending_cans.ogg'
|
||||
light_color = COLOR_PALE_BLUE_GRAY
|
||||
exclusive_screen = FALSE
|
||||
ui_size = 60
|
||||
|
||||
/obj/machinery/vending/boozeomat/ui_interact(mob/user, var/datum/topic_state/state = default_state)
|
||||
user.set_machine(src)
|
||||
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if(!ui)
|
||||
ui = new(user, src, "machinery-vending", 900, 600, capitalize(name), state=state)
|
||||
|
||||
v_asset = get_asset_datum(/datum/asset/spritesheet/vending/boozeomat)
|
||||
|
||||
ui.open(v_asset)
|
||||
|
||||
/obj/machinery/vending/assist
|
||||
vend_id = "tools"
|
||||
@@ -762,7 +773,6 @@
|
||||
icon_state = "dinnerware"
|
||||
vend_id = "cutlery"
|
||||
products = list(
|
||||
/obj/item/tray = 12,
|
||||
/obj/item/material/kitchen/utensil/fork = 12,
|
||||
/obj/item/material/kitchen/utensil/knife = 12,
|
||||
/obj/item/material/kitchen/utensil/spoon = 12,
|
||||
@@ -781,6 +791,7 @@
|
||||
/obj/item/reagent_containers/ladle = 4,
|
||||
/obj/item/storage/toolbox/lunchbox/nt = 6,
|
||||
/obj/item/reagent_containers/glass/rag = 8,
|
||||
/obj/item/tray = 12,
|
||||
)
|
||||
contraband = list(
|
||||
/obj/item/storage/toolbox/lunchbox/syndicate = 2
|
||||
|
||||
@@ -150,6 +150,7 @@ var/list/asset_datums = list()
|
||||
|
||||
/datum/asset
|
||||
var/_abstract = /datum/asset
|
||||
var/delayed = FALSE
|
||||
|
||||
/datum/asset/New()
|
||||
asset_datums[type] = src
|
||||
@@ -287,8 +288,11 @@ var/list/asset_datums = list()
|
||||
|
||||
return out.Join("\n")
|
||||
|
||||
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
|
||||
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE, icon/forced=FALSE)
|
||||
if(!forced)
|
||||
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
|
||||
else
|
||||
I = forced
|
||||
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
|
||||
return
|
||||
var/size_id = "[I.Width()]x[I.Height()]"
|
||||
@@ -322,12 +326,14 @@ var/list/asset_datums = list()
|
||||
/datum/asset/spritesheet/proc/css_tag()
|
||||
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
|
||||
|
||||
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
|
||||
/datum/asset/spritesheet/proc/icon_tag(sprite_name, var/html=TRUE)
|
||||
var/sprite = sprites[sprite_name]
|
||||
if (!sprite)
|
||||
return null
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
if(html)
|
||||
return {"<span class="[name][size_id] [sprite_name]"></span>"}
|
||||
return "[name][size_id] [sprite_name]"
|
||||
|
||||
#undef SPR_SIZE
|
||||
#undef SPR_IDX
|
||||
@@ -473,3 +479,123 @@ var/list/asset_datums = list()
|
||||
if(A.tag_icon)
|
||||
Insert(A.tag_icon, I, A.tag_icon)
|
||||
..()
|
||||
|
||||
/datum/asset/spritesheet/vending
|
||||
name = "vending"
|
||||
var/obj/machinery/vending/v_type = null
|
||||
delayed = TRUE
|
||||
|
||||
/datum/asset/spritesheet/vending/New()
|
||||
if(ispath(v_type))
|
||||
v_type = new v_type
|
||||
|
||||
if(istype(v_type) && v_type.name)
|
||||
name = ckey(v_type.name)
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/asset/spritesheet/vending/register()
|
||||
if(!istype(v_type))
|
||||
return
|
||||
for(var/products in list(v_type?.products, v_type?.contraband, v_type?.premium))
|
||||
for(var/o_path in products)
|
||||
var/obj/O = new o_path
|
||||
var/i_type = ckey("[O.type]")
|
||||
var/icon/I = icon(O.icon, O.icon_state)
|
||||
if(istype(O, /obj/item/seeds))
|
||||
// thanks seeds for being overlays defined at runtime
|
||||
var/obj/item/seeds/S = O
|
||||
I = S.update_appearance(TRUE)
|
||||
Insert(i_type, I, forced=I)
|
||||
else
|
||||
if(i_type in sprites)
|
||||
continue
|
||||
if(O.overlay_queued)
|
||||
O.compile_overlays()
|
||||
if(O.overlays.len)
|
||||
I = getFlatIcon(O)
|
||||
Insert(i_type, I, forced=I)
|
||||
else
|
||||
Insert(i_type, O.icon, O.icon_state)
|
||||
|
||||
..()
|
||||
|
||||
// v_type needs to be the path to the vending machine
|
||||
|
||||
/datum/asset/spritesheet/vending/vendors
|
||||
v_type = /obj/machinery/vending/vendors
|
||||
|
||||
/datum/asset/spritesheet/vending/boozeomat
|
||||
v_type = /obj/machinery/vending/boozeomat
|
||||
|
||||
/datum/asset/spritesheet/vending/assist
|
||||
v_type = /obj/machinery/vending/assist
|
||||
|
||||
/datum/asset/spritesheet/vending/coffee
|
||||
v_type = /obj/machinery/vending/coffee
|
||||
|
||||
/datum/asset/spritesheet/vending/snack
|
||||
v_type = /obj/machinery/vending/snack
|
||||
|
||||
/datum/asset/spritesheet/vending/cola
|
||||
v_type = /obj/machinery/vending/cola
|
||||
|
||||
/datum/asset/spritesheet/vending/cart
|
||||
v_type = /obj/machinery/vending/cart
|
||||
|
||||
/datum/asset/spritesheet/vending/cigarette
|
||||
v_type = /obj/machinery/vending/cigarette
|
||||
|
||||
/datum/asset/spritesheet/vending/medical
|
||||
v_type = /obj/machinery/vending/medical
|
||||
|
||||
/datum/asset/spritesheet/vending/phoronresearch
|
||||
v_type = /obj/machinery/vending/phoronresearch
|
||||
|
||||
/datum/asset/spritesheet/vending/wallmed1
|
||||
v_type = /obj/machinery/vending/wallmed1
|
||||
|
||||
/datum/asset/spritesheet/vending/wallmed2
|
||||
v_type = /obj/machinery/vending/wallmed2
|
||||
|
||||
/datum/asset/spritesheet/vending/security
|
||||
v_type = /obj/machinery/vending/security
|
||||
|
||||
/datum/asset/spritesheet/vending/hydronutrients
|
||||
v_type = /obj/machinery/vending/hydronutrients
|
||||
|
||||
/datum/asset/spritesheet/vending/hydroseeds
|
||||
v_type = /obj/machinery/vending/hydroseeds
|
||||
|
||||
/datum/asset/spritesheet/vending/magivend
|
||||
v_type = /obj/machinery/vending/magivend
|
||||
|
||||
/datum/asset/spritesheet/vending/dinnerware
|
||||
v_type = /obj/machinery/vending/dinnerware
|
||||
|
||||
/datum/asset/spritesheet/vending/sovietsoda
|
||||
v_type = /obj/machinery/vending/sovietsoda
|
||||
|
||||
/datum/asset/spritesheet/vending/tool
|
||||
v_type = /obj/machinery/vending/tool
|
||||
|
||||
/datum/asset/spritesheet/vending/engivend
|
||||
v_type = /obj/machinery/vending/engivend
|
||||
|
||||
/datum/asset/spritesheet/vending/tacticool
|
||||
v_type = /obj/machinery/vending/tacticool
|
||||
|
||||
/datum/asset/spritesheet/vending/tacticoolert
|
||||
v_type = /obj/machinery/vending/tacticool/ert
|
||||
|
||||
/datum/asset/spritesheet/vending/engineering
|
||||
v_type = /obj/machinery/vending/engineering
|
||||
|
||||
/datum/asset/spritesheet/vending/robotics
|
||||
v_type = /obj/machinery/vending/robotics
|
||||
|
||||
/datum/asset/spritesheet/vending/zora
|
||||
v_type = /obj/machinery/vending/zora
|
||||
|
||||
/datum/asset/spritesheet/vending/battlemonsters
|
||||
v_type = /obj/machinery/vending/battlemonsters
|
||||
|
||||
@@ -22,7 +22,7 @@ var/global/list/plant_seed_sprites = list()
|
||||
update_appearance()
|
||||
|
||||
//Updates strings and icon appropriately based on seed datum.
|
||||
/obj/item/seeds/proc/update_appearance()
|
||||
/obj/item/seeds/proc/update_appearance(var/ret_image = FALSE)
|
||||
if(!seed)
|
||||
return
|
||||
|
||||
@@ -58,6 +58,17 @@ var/global/list/plant_seed_sprites = list()
|
||||
src.name = "sample of [seed.seed_name] [seed.seed_noun]"
|
||||
src.desc = "It's labelled as coming from \a [seed.display_name]."
|
||||
|
||||
if(ret_image)
|
||||
var/icon/sm = icon('icons/obj/seeds.dmi', "[is_seeds ? "seed" : "spore"]-mask")
|
||||
var/icon/so = icon('icons/obj/seeds.dmi', "[seed.get_trait(TRAIT_PRODUCT_ICON)]")
|
||||
var/p_color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
so *= p_color
|
||||
if(is_seeds)
|
||||
var/s_color = seed.get_trait(TRAIT_PLANT_COLOUR)
|
||||
sm *= s_color
|
||||
sm.Blend(so, ICON_OVERLAY)
|
||||
return sm
|
||||
|
||||
/obj/item/seeds/examine(mob/user)
|
||||
..(user)
|
||||
if(seed && !seed.roundstart)
|
||||
|
||||
@@ -71,7 +71,7 @@ main ui datum.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/vueui/proc/open()
|
||||
/datum/vueui/proc/open(var/datum/asset/spritesheet/load_asset)
|
||||
if(QDELETED(object))
|
||||
return
|
||||
if(!user.client)
|
||||
@@ -86,8 +86,8 @@ main ui datum.
|
||||
var/params = "window=[windowid];file=[windowid];"
|
||||
if(width && height)
|
||||
params += "size=[width]x[height];"
|
||||
send_resources_and_assets(user.client)
|
||||
user << browse(generate_html(), params)
|
||||
send_resources_and_assets(user.client, load_asset)
|
||||
user << browse(generate_html(load_asset?.css_tag()), params)
|
||||
winset(user, "mapwindow.map", "focus=true")
|
||||
addtimer(CALLBACK(src, /datum/vueui/proc/setclose), 1)
|
||||
|
||||
@@ -123,7 +123,7 @@ main ui datum.
|
||||
*
|
||||
* @return html code - text
|
||||
*/
|
||||
/datum/vueui/proc/generate_html()
|
||||
/datum/vueui/proc/generate_html(var/css_tag)
|
||||
#ifdef UIDEBUG
|
||||
var/debugtxt = "<div id=\"dapp\"></div>"
|
||||
#else
|
||||
@@ -136,6 +136,7 @@ main ui datum.
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="vueui.css">
|
||||
[css_tag]
|
||||
</head>
|
||||
<body class="[get_theme_class()]">
|
||||
<div id="header">
|
||||
@@ -186,8 +187,10 @@ main ui datum.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/vueui/proc/send_resources_and_assets(var/client/cl)
|
||||
/datum/vueui/proc/send_resources_and_assets(var/client/cl, var/datum/asset/load_asset)
|
||||
send_theme_resources(cl)
|
||||
if(istype(load_asset))
|
||||
load_asset.send(cl)
|
||||
for(var/asset_name in assets)
|
||||
var/asset = assets[asset_name]
|
||||
var/image/I = asset["img"]
|
||||
|
||||
8
html/changelogs/johnwildkins-vend2.yml
Normal file
8
html/changelogs/johnwildkins-vend2.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
author: JohnWildkins
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- rscadd: "Vending machines now have a graphical, icon-based item interface based in VueUI."
|
||||
- tweak: "Vending machines now have a search bar."
|
||||
- bugfix: "Icon lag when using vending machines should no longer exist."
|
||||
191
vueui/src/components/view/machinery/vending.vue
Normal file
191
vueui/src/components/view/machinery/vending.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="s.mode == 0 || s.sel_price == 0">
|
||||
<div class="cancel-button">
|
||||
<vui-input-search :input="products" v-model="output" :keys="['name']" autofocus :threshold="threshold" />
|
||||
<vui-button :disabled="!s.coin" :params="{ remove_coin: 1 }" icon="sign-out-alt">{{ s.coin ? s.coin : "No coin inserted." }}</vui-button>
|
||||
</div>
|
||||
<div class="t-parent">
|
||||
<vui-button v-for="vend in output" :key="vend.key" :class="vend.amount > 0 ? '' : 'no-stock'"
|
||||
class="t-child tooltip" :disabled="vend.amount == 0 || s.mode == 1" :params="{ vendItem: vend.key }">
|
||||
<div class="t-container" :style="{ height: s.ui_size + 'px', width: s.ui_size + 'px'}">
|
||||
<span :class="[vend.amount > 0 ? '' : 'no-stock', vend.icon_tag]" class="food-icon"/>
|
||||
<span v-if="vend.price > 0" class="cart-icon fas ic-shopping-cart"/>
|
||||
<span v-if="vend.price > 0" class="price">{{ vend.price }}电</span>
|
||||
<span class="qty" :class="vend.amount > 0 ? '' : 'no-stock'">(x{{ vend.amount }})</span>
|
||||
</div>
|
||||
<span class="tooltiptext">{{ vend.name }}</span>
|
||||
</vui-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="s.sel_name && s.sel_price > 0">
|
||||
<div class="t-parent">
|
||||
<p>Item selected:<span class="purchase-icon" :class="s.sel_icon" />{{s.sel_name}}</p>
|
||||
<p>Charge: {{s.sel_price}}电 / {{s.sel_price}}cr</p>
|
||||
<p>Swipe your NanoTrasen ID or insert credits to purchase.</p>
|
||||
<p v-if="s.message_err == 1" class="danger">{{s.message}}</p>
|
||||
<div class="cancel-button">
|
||||
<vui-button :params="{ cancelpurchase: 1 }" icon="undo">Cancel Transaction</vui-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<vui-button class="cancel-button danger" :params="{ reset: 1}" icon="undo">Reset Machine</vui-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
s: this.$root.$data.state,
|
||||
output: [],
|
||||
threshold: 0.3
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
products() {
|
||||
return Object.values(this.s.products);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.t-parent > p {
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
p.danger {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.purchase-icon {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.food-icon {
|
||||
// zoom: 2;
|
||||
transform: scale(2);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.food-icon.no-stock {
|
||||
opacity: 0.2;
|
||||
filter: alpha(opacity=20);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
||||
// god knows which one of these we actually need so let's just use them all
|
||||
}
|
||||
|
||||
.t-parent {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
outline-style: ridge;
|
||||
outline-color: black;
|
||||
}
|
||||
|
||||
.t-child {
|
||||
height: auto;
|
||||
white-space: normal;
|
||||
box-sizing: border-box;
|
||||
margin: 4px 4px 4px 4px;
|
||||
background-color: rgba(64, 98, 138, 0.4);
|
||||
}
|
||||
|
||||
.t-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.statusValue {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.no-stock {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.cart-icon {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.price {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 0;
|
||||
right: 15px;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.qty {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 4px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.no-stock.button {
|
||||
background: inherit;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Tooltip container */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Tooltip text */
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
width: 120px;
|
||||
background-color: #202020;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
border-radius: 6px;
|
||||
opacity: 0;
|
||||
transition: opacity 1s;
|
||||
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -60px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.tooltip .tooltiptext::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: #202020 transparent transparent transparent;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user