mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
Fix vendor stock bug, make vendor dispensing behaviours apply more (#90266)
## About The Pull Request So #90246 was caused purely because vendors don't actually reduce the stock when dispensing returned items: https://github.com/tgstation/tgstation/blob/c0204da3da7388d9a0b28523a66b83bcc7a29f23/code/modules/vending/_vending.dm#L1464-L1467 While this could've been a single line fix by just decrementing the stock like how returned items are handled elsewhere, instead we collapse all these cases into being handled by `dispense(...)` so it's harder for this to happen again. We make this a parameter because different dispensing methods have different priorities. As a side, we make it so `on_dispense(...)` forwards whether or not it's a returned item, because logically mothroach infestations would still snack on your clothes even if they're just returned. I felt it best to make them deal less damage to returned clothes in that case. ## Why It's Good For The Game Fixes #90246. Fixes #89104. Good if the special vendor stuff gets applied when items are thrown too Being able to cycle items through the mothroach clothing gnawing machine is funny ## Changelog 🆑 fix: Dispensing a returned item from a vendor actually reduces the amount of stock for that item. fix: Special vendor dispensing behaviours get applied to thrown items. fix: Special vendor dispensing behaviours actually get applied to returned items where applicable. /🆑
This commit is contained in:
@@ -379,11 +379,9 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
found_anything = FALSE
|
||||
for(var/datum/data/vending_product/record as anything in shuffle(product_records))
|
||||
//first dump any of the items that have been returned, in case they contain the nuke disk or something
|
||||
for(var/obj/returned_obj_to_dump in record.returned_products)
|
||||
LAZYREMOVE(record.returned_products, returned_obj_to_dump)
|
||||
returned_obj_to_dump.forceMove(get_turf(src))
|
||||
for(var/i in 1 to LAZYLEN(record.returned_products))
|
||||
var/obj/item/returned_obj_to_dump = dispense(record, get_turf(src), dispense_returned = TRUE)
|
||||
step(returned_obj_to_dump, pick(GLOB.alldirs))
|
||||
record.amount--
|
||||
|
||||
if(record.amount <= 0) //Try to use a record that actually has something to dump.
|
||||
continue
|
||||
@@ -788,13 +786,9 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
|
||||
if(record.amount <= 0) //Try to use a record that actually has something to dump.
|
||||
continue
|
||||
if(record.amount > LAZYLEN(record.returned_products)) //always give out new stuff that costs before free returned stuff, because of the risk getting gibbed involved
|
||||
dispense(record, get_turf(src), silent = TRUE)
|
||||
else
|
||||
var/obj/returned_obj_to_dump = LAZYACCESS(record.returned_products, LAZYLEN(record.returned_products)) //first in, last out
|
||||
LAZYREMOVE(record.returned_products, returned_obj_to_dump)
|
||||
returned_obj_to_dump.forceMove(get_turf(src))
|
||||
record.amount--
|
||||
// Always give out new stuff that costs before free returned stuff, because of the risk getting gibbed involved
|
||||
var/only_returned_left = (record.amount <= LAZYLEN(record.returned_products))
|
||||
dispense(record, get_turf(src), silent = TRUE, dispense_returned = only_returned_left)
|
||||
break
|
||||
deploy_credits()
|
||||
|
||||
@@ -1457,14 +1451,11 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
use_energy(active_power_usage)
|
||||
if(icon_vend) //Show the vending animation if needed
|
||||
flick(icon_vend,src)
|
||||
var/obj/item/vended_item
|
||||
if(!LAZYLEN(item_record.returned_products)) //always give out free returned stuff first, e.g. to avoid walling a traitor objective in a bag behind paid items
|
||||
vended_item = dispense(item_record, get_turf(src))
|
||||
else
|
||||
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
|
||||
vended_item = LAZYACCESS(item_record.returned_products, LAZYLEN(item_record.returned_products)) //first in, last out
|
||||
LAZYREMOVE(item_record.returned_products, vended_item)
|
||||
vended_item.forceMove(get_turf(src))
|
||||
|
||||
// Always give out free returned stuff first, e.g. to avoid walling a traitor objective in a bag behind paid items
|
||||
var/returned_available = LAZYLEN(item_record.returned_products)
|
||||
var/obj/item/vended_item = dispense(item_record, get_turf(src), dispense_returned = returned_available)
|
||||
|
||||
if(greyscale_colors)
|
||||
vended_item.set_greyscale(colors=greyscale_colors)
|
||||
if(usr.CanReach(src) && usr.put_in_hands(vended_item))
|
||||
@@ -1475,19 +1466,27 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
vend_ready = TRUE
|
||||
|
||||
///Common proc that dispenses an item. Called when the item is vended, or gotten some other way.
|
||||
/obj/machinery/vending/proc/dispense(datum/data/vending_product/item_record, atom/spawn_location, silent = FALSE)
|
||||
/obj/machinery/vending/proc/dispense(datum/data/vending_product/item_record, atom/spawn_location, silent = FALSE, dispense_returned = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(!silent)
|
||||
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
|
||||
var/obj/item/vended_item = new item_record.product_path (spawn_location)
|
||||
if(vended_item.type in contraband)
|
||||
ADD_TRAIT(vended_item, TRAIT_CONTRABAND, INNATE_TRAIT)
|
||||
on_dispense(vended_item)
|
||||
|
||||
var/obj/item/vended_item
|
||||
if(dispense_returned)
|
||||
vended_item = LAZYACCESS(item_record.returned_products, LAZYLEN(item_record.returned_products)) //first in, last out
|
||||
LAZYREMOVE(item_record.returned_products, vended_item)
|
||||
vended_item.forceMove(spawn_location)
|
||||
else
|
||||
vended_item = new item_record.product_path(spawn_location)
|
||||
if(vended_item.type in contraband)
|
||||
ADD_TRAIT(vended_item, TRAIT_CONTRABAND, INNATE_TRAIT)
|
||||
|
||||
on_dispense(vended_item, dispense_returned)
|
||||
item_record.amount--
|
||||
return vended_item
|
||||
|
||||
///A proc meant to perform custom behavior on newly dispensed items.
|
||||
/obj/machinery/vending/proc/on_dispense(obj/item/vended_item)
|
||||
/obj/machinery/vending/proc/on_dispense(obj/item/vended_item, dispense_returned = FALSE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -1578,32 +1577,28 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
* This item is then created and tossed out in front of us with a visible message
|
||||
*/
|
||||
/obj/machinery/vending/proc/throw_item()
|
||||
var/obj/throw_item = null
|
||||
var/mob/living/target = locate() in view(7,src)
|
||||
if(!target)
|
||||
return FALSE
|
||||
|
||||
var/obj/thrown_item
|
||||
for(var/datum/data/vending_product/record in shuffle(product_records))
|
||||
if(record.amount <= 0) //Try to use a record that actually has something to dump.
|
||||
continue
|
||||
var/dump_path = record.product_path
|
||||
if(!dump_path)
|
||||
continue
|
||||
if(record.amount > LAZYLEN(record.returned_products)) //always throw new stuff that costs before free returned stuff, because of the hacking effort and time between throws involved
|
||||
throw_item = new dump_path(loc)
|
||||
else
|
||||
throw_item = LAZYACCESS(record.returned_products, LAZYLEN(record.returned_products)) //first in, last out
|
||||
throw_item.forceMove(loc)
|
||||
LAZYREMOVE(record.returned_products, throw_item)
|
||||
record.amount--
|
||||
// Always throw new stuff that costs before free returned stuff, because of the hacking effort and time between throws involved
|
||||
var/only_returned_left = (record.amount <= LAZYLEN(record.returned_products))
|
||||
thrown_item = dispense(record, get_turf(src), silent = TRUE, dispense_returned = only_returned_left)
|
||||
break
|
||||
if(!throw_item)
|
||||
if(isnull(thrown_item))
|
||||
return FALSE
|
||||
|
||||
pre_throw(throw_item)
|
||||
pre_throw(thrown_item)
|
||||
|
||||
throw_item.throw_at(target, 16, 3)
|
||||
visible_message(span_danger("[src] launches [throw_item] at [target]!"))
|
||||
thrown_item.throw_at(target, 16, 3)
|
||||
visible_message(span_danger("[src] launches [thrown_item] at [target]!"))
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,10 @@
|
||||
/datum/reagent/consumable/ethanol/neurotoxin = 1,
|
||||
)
|
||||
|
||||
/obj/machinery/vending/cola/on_dispense(obj/item/vended_item)
|
||||
/obj/machinery/vending/cola/on_dispense(obj/item/vended_item, dispense_returned = FALSE)
|
||||
// Only apply to newly dispensed items
|
||||
if(dispense_returned)
|
||||
return
|
||||
// 35% chance that your drink will be safe, as safe pure acid and sugar that these drinks probably are can be
|
||||
if(!onstation || !HAS_TRAIT(SSstation, STATION_TRAIT_SPIKED_DRINKS) || !prob(65))
|
||||
return
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
icon_state = "refill_snack"
|
||||
|
||||
/// Cute little thing that sets it apart from the other food vending mahicnes. I mean, you don't find this every day.
|
||||
/obj/machinery/vending/hotdog/on_dispense(obj/item/vended_item)
|
||||
/obj/machinery/vending/hotdog/on_dispense(obj/item/vended_item, dispense_returned = FALSE)
|
||||
// Only apply to newly dispensed items
|
||||
if(dispense_returned)
|
||||
return
|
||||
if(istype(vended_item, /obj/item/food))
|
||||
ADD_TRAIT(vended_item, TRAIT_FOOD_CHEF_MADE, VENDING_MACHINE_TRAIT)
|
||||
|
||||
@@ -23,11 +23,13 @@ GLOBAL_VAR_INIT(roaches_deployed, FALSE)
|
||||
GLOB.roaches_deployed = TRUE
|
||||
|
||||
|
||||
/obj/machinery/vending/wardrobe/on_dispense(obj/item/clothing/food)
|
||||
/obj/machinery/vending/wardrobe/on_dispense(obj/item/clothing/food, dispense_returned = FALSE)
|
||||
if(!istype(food))
|
||||
return
|
||||
for(var/mob/living/basic/mothroach/roach in contents)
|
||||
food.take_damage(food.get_integrity() * 0.5)
|
||||
// Be slightly nicer on returned items
|
||||
var/damage_mult = dispense_returned ? 0.1 : 0.5
|
||||
food.take_damage(food.get_integrity() * damage_mult)
|
||||
|
||||
/obj/machinery/vending/wardrobe/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user