diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index f88795c30d5..0eb119a09d5 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -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 /** diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index bcc44dfedf9..9352c0c8b10 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -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 diff --git a/code/modules/vending/hotdog.dm b/code/modules/vending/hotdog.dm index 094beccb413..9d89702a923 100644 --- a/code/modules/vending/hotdog.dm +++ b/code/modules/vending/hotdog.dm @@ -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) diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 634639d8bed..f24dc687f3e 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -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) . = ..()