diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 43208497026..d9dad06528e 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -658,6 +658,33 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/manipulator = 2, /obj/item/reagent_containers/glass/beaker = 2) +/obj/item/circuitboard/dish_drive + board_name = "Dish Drive" + build_path = /obj/machinery/dish_drive + board_type = "machine" + origin_tech = "programming=2" + req_components = list( + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/matter_bin = 1, + /obj/item/stack/sheet/glass = 1) + var/suction = TRUE + var/transmit = TRUE + +/obj/item/circuitboard/dish_drive/examine(mob/user) + . = ..() + . += "Its suction function is [suction ? "enabled" : "disabled"]. Use it in-hand to switch." + . += "Its disposal auto-transmit function is [transmit ? "enabled" : "disabled"]. Alt-click it to switch." + +/obj/item/circuitboard/dish_drive/attack_self(mob/living/user) + suction = !suction + to_chat(user, "You [suction ? "enable" : "disable"] the board's suction function.") + +/obj/item/circuitboard/dish_drive/AltClick(mob/living/user) + if(!user.Adjacent(src)) + return + transmit = !transmit + to_chat(user, "You [transmit ? "enable" : "disable"] the board's automatic disposal transmission.") + /obj/item/circuitboard/chem_dispenser/soda board_name = "Soda Machine" build_path = /obj/machinery/chem_dispenser/soda diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm new file mode 100644 index 00000000000..ad505a4bf5f --- /dev/null +++ b/code/game/machinery/dish_drive.dm @@ -0,0 +1,134 @@ +/obj/machinery/dish_drive + name = "dish drive" + desc = "A culinary marvel that uses matter-to-energy conversion to store dishes and shards. Convenient! \ + Additional features include a vacuum function to suck in nearby dishes, and an automatic transfer beam that empties its contents into nearby disposal bins every now and then. \ + Or you can just drop your plates on the floor, like civilized folk." + icon = 'icons/obj/kitchen.dmi' + icon_state = "synthesizer" + idle_power_usage = 8 //5 with default parts + active_power_usage = 13 //10 with default parts + anchored = FALSE + density = FALSE + pass_flags = PASSTABLE + var/static/list/collectable_items = list(/obj/item/trash/waffles, + /obj/item/trash/plate, + /obj/item/trash/tray, + /obj/item/reagent_containers/food/drinks/drinkingglass, + /obj/item/kitchen/utensil/fork, + /obj/item/shard, + /obj/item/broken_bottle) + var/static/list/disposable_items = list(/obj/item/trash/waffles, + /obj/item/trash/plate, + /obj/item/trash/tray, + /obj/item/shard, + /obj/item/broken_bottle) + var/time_since_dishes = 0 + var/suction_enabled = TRUE + var/transmit_enabled = TRUE + var/list/dish_drive_contents + +/obj/machinery/dish_drive/Initialize(mapload) + . = ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/dish_drive(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stack/sheet/glass(null) + RefreshParts() + +/obj/machinery/dish_drive/examine(mob/user) + . = ..() + if(user.Adjacent(src)) + . += "Alt-click it to beam its waste storage contents to any nearby disposal bins." + +/obj/machinery/dish_drive/attack_hand(mob/living/user) + if(!LAZYLEN(dish_drive_contents)) + to_chat(user, "There's nothing in [src]!") + return + var/obj/item/I = LAZYACCESS(dish_drive_contents, LAZYLEN(dish_drive_contents)) //the most recently-added item + LAZYREMOVE(dish_drive_contents, I) + user.put_in_hands(I) + to_chat(user, "You take out [I] from [src].") + playsound(src, 'sound/items/pshoom.ogg', 15, TRUE) + flick("synthesizer_beam", src) + +/obj/machinery/dish_drive/screwdriver_act(mob/user, obj/item/I) + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) + return TRUE + +/obj/machinery/dish_drive/wrench_act(mob/user, obj/item/I) + if(default_unfasten_wrench(user, I)) + return TRUE + +/obj/machinery/dish_drive/RefreshParts() + idle_power_usage = initial(idle_power_usage) + active_power_usage = initial(active_power_usage) + use_power = initial(use_power) + var/total_rating = 0 + for(var/obj/item/stock_parts/S in component_parts) + total_rating += S.rating + if(total_rating >= 9) + active_power_usage = 0 + use_power = NO_POWER_USE + else + idle_power_usage = max(0, idle_power_usage - total_rating) + active_power_usage = max(0, active_power_usage - total_rating) + var/obj/item/circuitboard/dish_drive/board = locate() in component_parts + if(board) + suction_enabled = board.suction + transmit_enabled = board.transmit + +/obj/machinery/dish_drive/process() + if(time_since_dishes <= world.time && transmit_enabled) + do_the_dishes() + if(!suction_enabled) + return + for(var/obj/item/I in view(4, src)) + if(is_type_in_list(I, collectable_items) && I.loc != src && (!I.reagents || !I.reagents.total_volume)) + if(I.Adjacent(src)) + LAZYADD(dish_drive_contents, I) + visible_message("[src] beams up [I]!") + I.forceMove(src) + playsound(src, 'sound/items/pshoom.ogg', 15, TRUE) + flick("synthesizer_beam", src) + else + step_towards(I, src) + +/obj/machinery/dish_drive/attack_ai(mob/living/user) + if(stat) + return + to_chat(user, "You send a disposal transmission signal to [src].") + do_the_dishes(TRUE) + +/obj/machinery/dish_drive/AltClick(mob/living/user) + if(user.can_use(src, !issilicon(user))) + do_the_dishes(TRUE) + +/obj/machinery/dish_drive/proc/do_the_dishes(manual) + if(!LAZYLEN(dish_drive_contents)) + if(manual) + visible_message("[src] is empty!") + return + var/obj/machinery/disposal/bin = locate() in view(7, src) + if(!bin) + if(manual) + visible_message("[src] buzzes. There are no disposal bins in range!") + playsound(src, 'sound/machines/buzz-sigh.ogg', 15, TRUE) + return + var/disposed = 0 + for(var/obj/item/I in dish_drive_contents) + if(is_type_in_list(I, disposable_items)) + LAZYREMOVE(dish_drive_contents, I) + I.forceMove(bin) + use_power(active_power_usage) + disposed++ + if(disposed) + visible_message("[src] [pick("whooshes", "bwooms", "fwooms", "pshooms")] and beams [disposed] stored item\s into the nearby [bin.name].") + playsound(src, 'sound/items/pshoom.ogg', 15, TRUE) + playsound(bin, 'sound/items/pshoom.ogg', 15, TRUE) + Beam(bin, icon_state = "rped_upgrade", time = 5) + bin.update_icon() + flick("synthesizer_beam", src) + else + visible_message("There are no disposable items in [src]!") + time_since_dishes = world.time + 60 SECONDS diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 09e8bb8122a..711b40784e4 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -2219,6 +2219,7 @@ /obj/item/clothing/accessory/waistcoat = 2, /obj/item/reagent_containers/glass/rag = 3) contraband = list(/obj/item/toy/figure/crew/chef = 1) + premium = list(/obj/item/storage/box/dish_drive = 1) refill_canister = /obj/item/vending_refill/chefdrobe /obj/machinery/vending/bardrobe @@ -2239,6 +2240,7 @@ /obj/item/clothing/accessory/waistcoat = 2, /obj/item/reagent_containers/glass/rag = 3) contraband = list(/obj/item/toy/figure/crew/bartender = 1) + premium = list(/obj/item/storage/box/dish_drive = 1) refill_canister = /obj/item/vending_refill/bardrobe /obj/machinery/vending/hydrodrobe diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 9efb1862639..8d1267d80be 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -917,6 +917,19 @@ new /obj/item/implantcase/mindshield(src) new /obj/item/implanter/mindshield(src) +/obj/item/storage/box/dish_drive + name = "DIY Dish Drive Kit" + desc = "Contains everything you need to build your own Dish Drive!" + +/obj/item/storage/box/dish_drive/populate_contents() + new /obj/item/stack/sheet/metal/(src, 5) + new /obj/item/stack/cable_coil/five(src) + new /obj/item/circuitboard/dish_drive(src) + new /obj/item/stack/sheet/glass(src) + new /obj/item/stock_parts/manipulator(src) + new /obj/item/stock_parts/matter_bin(src) + new /obj/item/screwdriver(src) + #undef NODESIGN #undef NANOTRASEN #undef SYNDI diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 67b9dc11e1e..d32cfcf7a7c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -975,6 +975,15 @@ visible_message("[user] butchers [src].") gib() +/mob/living/proc/can_use(atom/movable/M, be_close = FALSE) + if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) + to_chat(src, "You can't do that right now!") + return FALSE + if(be_close && !in_range(M, src)) + to_chat(src, "You are too far away!") + return FALSE + return TRUE + /mob/living/movement_delay(ignorewalk = 0) . = ..() if(isturf(loc)) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 7bb38b242c3..d3d9003780a 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -515,7 +515,6 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe/cable_restrain /obj/item/stack/cable_coil/New(loc, length = MAXCOIL, paramcolor = null) ..() - amount = length if(paramcolor) color = paramcolor pixel_x = rand(-2,2) @@ -835,6 +834,13 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe/cable_restrain update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) update_wclass() + +/obj/item/stack/cable_coil/five + +// Passes '5' to the parent as `new_amount`, so 5 coils are created. +/obj/item/stack/cable_coil/five/New(loc, new_amount = 5, merge = TRUE, paramcolor = null) + ..() + /obj/item/stack/cable_coil/yellow color = COLOR_YELLOW diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 663490496b6..c261251744e 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -342,6 +342,16 @@ build_path = /obj/item/circuitboard/smartfridge category = list ("Misc. Machinery") +/datum/design/dish_drive + name = "Machine Design (Dish Drive Board)" + desc = "The circuit board for a dish drive." + id = "dishdrive" + req_tech = list("programming" = 1) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + build_path = /obj/item/circuitboard/dish_drive + category = list("Misc. Machinery") + /datum/design/monkey_recycler name = "Machine Design (Monkey Recycler Board)" desc = "The circuit board for a monkey recycler." diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index 0d13c90cd15..c162b1007d8 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/paradise.dme b/paradise.dme index b2c5bd9e7df..1c3b64e937d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -672,6 +672,7 @@ #include "code\game\machinery\cryopod.dm" #include "code\game\machinery\dance_machine.dm" #include "code\game\machinery\defib_mount.dm" +#include "code\game\machinery\dish_drive.dm" #include "code\game\machinery\deployable.dm" #include "code\game\machinery\door_control.dm" #include "code\game\machinery\doppler_array.dm"