mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-10 07:41:16 +01:00
652fd2633e
## About The Pull Request The post_restock proc did not have an appropriate check to confirm that there was enough stored credits to produce a non-zero holochip. This adds a quick check for the proc, preventing their creation. ## Why It's Good For The Game One less silly runtime on live. ## Changelog 🆑 fix: Restocking a vending machine can no longer produce a zero credit holochip. /🆑
244 lines
8.6 KiB
Plaintext
244 lines
8.6 KiB
Plaintext
//===============================HAND INTERACTION===================================
|
|
/obj/machinery/vending/interact(mob/user)
|
|
if(seconds_electrified && !(machine_stat & NOPOWER))
|
|
if(shock(user, 100))
|
|
return
|
|
|
|
if(tilted && !user.buckled)
|
|
to_chat(user, span_notice("You begin righting [src]."))
|
|
if(do_after(user, 5 SECONDS, target = src))
|
|
untilt(user)
|
|
return
|
|
|
|
return ..()
|
|
|
|
//================================TOOL ACTS==============================================
|
|
/obj/machinery/vending/crowbar_act(mob/living/user, obj/item/attack_item)
|
|
if(!component_parts)
|
|
return ITEM_INTERACT_FAILURE
|
|
return default_deconstruction_crowbar(user, attack_item)
|
|
|
|
/obj/machinery/vending/wrench_act(mob/living/user, obj/item/tool)
|
|
. = NONE
|
|
if(!panel_open)
|
|
return ITEM_INTERACT_FAILURE
|
|
if(default_unfasten_wrench(user, tool, time = 6 SECONDS))
|
|
unbuckle_all_mobs(TRUE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/vending/screwdriver_act(mob/living/user, obj/item/attack_item)
|
|
if(anchored)
|
|
return default_deconstruction_screwdriver(user, attack_item)
|
|
to_chat(user, span_warning("You must first secure [src]."))
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
/obj/machinery/vending/on_set_panel_open(old_value)
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
|
|
//=======================================RESTOCKING==========================================
|
|
/**
|
|
* Is the passed in user allowed to load this vending machines compartments? This only is ran if we are using a /obj/item/storage/bag to load the vending machine, and not a dedicated restocker.
|
|
*
|
|
* Arguments:
|
|
* * user - mob that is doing the loading of the vending machine
|
|
*/
|
|
/obj/machinery/vending/proc/compartmentLoadAccessCheck(mob/user)
|
|
PROTECTED_PROC(TRUE)
|
|
|
|
return !req_access || allowed(user) || (obj_flags & EMAGGED) || !scan_id
|
|
|
|
/**
|
|
* Are we able to load the item passed in
|
|
*
|
|
* Arguments:
|
|
* * loaded_item - the item being loaded
|
|
* * user - the user doing the loading
|
|
*/
|
|
/obj/machinery/vending/proc/canLoadItem(obj/item/loaded_item, mob/user, send_message = TRUE)
|
|
PROTECTED_PROC(TRUE)
|
|
|
|
if(!length(loaded_item.contents) && (products[loaded_item.type] || premium[loaded_item.type] || contraband[loaded_item.type]))
|
|
return TRUE
|
|
if(send_message)
|
|
to_chat(user, span_warning("[src] does not accept [loaded_item]!"))
|
|
return FALSE
|
|
|
|
|
|
/**
|
|
* Tries to insert the item into the vendor, and depending on whether the product is a part of the vendor's
|
|
* stock or not, increments an already present product entry's available amount or creates a new entry.
|
|
* arguments:
|
|
* inserted_item - the item we're trying to insert
|
|
* user - mob who's trying to insert the item
|
|
*/
|
|
/obj/machinery/vending/proc/loadingAttempt(obj/item/inserted_item, mob/user)
|
|
PROTECTED_PROC(TRUE)
|
|
|
|
. = TRUE
|
|
if(!canLoadItem(inserted_item, user))
|
|
return FALSE
|
|
|
|
for(var/datum/data/vending_product/product_datum in product_records + coin_records + hidden_records)
|
|
if(inserted_item.type != product_datum.product_path)
|
|
continue
|
|
|
|
if(product_datum.amount == product_datum.max_amount)
|
|
to_chat(user, span_warning("[src] can't accept any more [inserted_item.name][inserted_item.p_s()]!"))
|
|
return FALSE
|
|
|
|
if(!user.transferItemToLoc(inserted_item, src))
|
|
to_chat(user, span_warning("[inserted_item] is stuck in your hand!"))
|
|
return FALSE
|
|
|
|
product_datum.amount++
|
|
LAZYADD(product_datum.returned_products, inserted_item)
|
|
to_chat(user, span_notice("You insert [inserted_item] into [src]'s input compartment."))
|
|
break
|
|
|
|
/obj/machinery/vending/item_interaction(mob/living/user, obj/item/attack_item, list/modifiers)
|
|
. = ..()
|
|
if(. & ITEM_INTERACT_ANY_BLOCKER)
|
|
return .
|
|
|
|
if(panel_open && is_wire_tool(attack_item))
|
|
wires.interact(user)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if(refill_canister && istype(attack_item, refill_canister))
|
|
. = ITEM_INTERACT_FAILURE
|
|
if (!panel_open)
|
|
to_chat(user, span_warning("You should probably unscrew the service panel first!"))
|
|
else if (!is_operational)
|
|
to_chat(user, span_warning("[src] does not respond."))
|
|
else
|
|
var/obj/item/vending_refill/canister = attack_item
|
|
if(canister.get_part_rating() == 0)
|
|
to_chat(user, span_warning("[canister] is empty!"))
|
|
else
|
|
post_restock(user, restock(canister))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if(compartmentLoadAccessCheck(user) && !user.combat_mode)
|
|
. = ITEM_INTERACT_FAILURE
|
|
if (!is_operational)
|
|
to_chat(user, span_warning("[src] does not respond."))
|
|
else if(istype(attack_item, /obj/item/storage/bag)) //trays USUALLY
|
|
var/obj/item/storage/storage_item = attack_item
|
|
var/loaded = 0
|
|
var/denied_items = 0
|
|
for(var/obj/item/the_item in storage_item.contents)
|
|
if(loadingAttempt(the_item, user))
|
|
loaded++
|
|
else
|
|
denied_items++
|
|
if(denied_items)
|
|
to_chat(user, span_warning("[src] refuses some items!"))
|
|
if(loaded)
|
|
to_chat(user, span_notice("You insert [loaded] dishes into [src]'s compartment."))
|
|
return ITEM_INTERACT_SUCCESS
|
|
else
|
|
return loadingAttempt(attack_item, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_FAILURE
|
|
|
|
/**
|
|
* After-effects of refilling a vending machine from a refill canister
|
|
*
|
|
* This takes the amount of products restocked and gives the user our contained credits if needed,
|
|
* sending the user a fitting message.
|
|
*
|
|
* Arguments:
|
|
* * user - the user restocking us
|
|
* * restocked - the amount of items we've been refilled with
|
|
*/
|
|
/obj/machinery/vending/proc/post_restock(mob/living/user, restocked)
|
|
PROTECTED_PROC(TRUE)
|
|
|
|
if(!restocked)
|
|
to_chat(user, span_warning("There's nothing to restock!"))
|
|
return
|
|
|
|
to_chat(user, span_notice("You loaded [restocked] items in [src][credits_contained > 0 ? ", and are rewarded [credits_contained] [MONEY_NAME]." : "."]"))
|
|
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
|
cargo_account.adjust_money(round(credits_contained * 0.5), "Vending: Restock")
|
|
if(credits_contained >= 1)
|
|
var/obj/item/holochip/payday = new(src, credits_contained)
|
|
try_put_in_hand(payday, user)
|
|
credits_contained = 0
|
|
|
|
/obj/machinery/vending/exchange_parts(mob/user, obj/item/storage/part_replacer/replacer)
|
|
if(!istype(replacer) || !component_parts || !refill_canister)
|
|
return FALSE
|
|
|
|
var/works_from_distance = istype(replacer, /obj/item/storage/part_replacer/bluespace)
|
|
|
|
if(!panel_open || works_from_distance)
|
|
to_chat(user, display_parts(user))
|
|
|
|
if(!panel_open && !works_from_distance)
|
|
return FALSE
|
|
|
|
var/restocked = 0
|
|
for(var/replacer_item in replacer)
|
|
if(istype(replacer_item, refill_canister))
|
|
restocked += restock(replacer_item)
|
|
post_restock(user, restocked)
|
|
if(restocked > 0)
|
|
replacer.play_rped_effect()
|
|
return TRUE
|
|
|
|
//=======================================ATTACKS================================================
|
|
/**
|
|
* Dispenses free items from the standard stock.
|
|
*
|
|
* Arguments:
|
|
* freebies - number of free items to vend
|
|
*/
|
|
/obj/machinery/vending/proc/freebie(freebies)
|
|
PRIVATE_PROC(TRUE)
|
|
|
|
visible_message(span_notice("[src] yields [freebies > 1 ? "several free goodies" : "a free goody"][credits_contained > 0 ? " and some [MONEY_NAME]" : ""]!"))
|
|
|
|
for(var/i in 1 to freebies)
|
|
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
|
|
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
|
|
// 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
|
|
|
|
if(credits_contained > 0)
|
|
var/credits_to_remove = min(CREDITS_DUMP_THRESHOLD, round(credits_contained))
|
|
var/obj/item/holochip/holochip = new(loc, credits_to_remove)
|
|
playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE)
|
|
credits_contained = max(0, credits_contained - credits_to_remove)
|
|
SSblackbox.record_feedback("amount", "vending machine looted", holochip.credits)
|
|
|
|
/obj/machinery/vending/attacked_by(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
|
|
. = ..()
|
|
if(!tiltable || tilted || . <= 0)
|
|
return
|
|
if(isclosedturf(get_turf(user))) //If the attacker is inside of a wall, immediately fall in the other direction, with no chance for goodies.
|
|
tilt(get_turf(get_step(src, REVERSE_DIR(get_dir(src, user)))))
|
|
return
|
|
|
|
switch(rand(1, 100))
|
|
if(1 to 5)
|
|
freebie(3)
|
|
if(6 to 15)
|
|
freebie(2)
|
|
if(16 to 25)
|
|
freebie(1)
|
|
if(26 to 75)
|
|
pass()
|
|
if(76 to 100)
|
|
tilt(user)
|
|
|
|
/obj/machinery/vending/attack_tk_grab(mob/user)
|
|
to_chat(user, span_warning("[src] seems to resist your mental grasp!"))
|
|
|
|
/obj/machinery/vending/attack_robot_secondary(mob/user, list/modifiers)
|
|
. = ..()
|
|
if (!Adjacent(user, src))
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|