diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 5a01fa82547..df2d47e8ba7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1008,7 +1008,7 @@ return SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, microwave_source, microwaver, randomize_pixel_offset) -//Used to check for extra requirements for blending(grinding or juicing) an object +///Used to check for extra requirements for blending(grinding or juicing) an object /obj/item/proc/blend_requirements(obj/machinery/reagentgrinder/R) return TRUE @@ -1018,15 +1018,16 @@ ///Grind item, adding grind_results to item's reagents and transfering to target_holder if specified /obj/item/proc/grind(datum/reagents/target_holder, mob/user) + . = FALSE if(on_grind() == -1) - return FALSE + return if(length(grind_results)) target_holder.add_reagent_list(grind_results) + . = TRUE if(reagents?.total_volume) reagents.trans_to(target_holder, reagents.total_volume, transferred_by = user) - - return TRUE + . = TRUE ///Called BEFORE the object is ground up - use this to change grind results based on conditions. Return "-1" to prevent the grinding from occurring /obj/item/proc/on_juice() diff --git a/code/game/objects/items/rcd/RPLD.dm b/code/game/objects/items/rcd/RPLD.dm index 21e68bd92dd..8ae38982692 100644 --- a/code/game/objects/items/rcd/RPLD.dm +++ b/code/game/objects/items/rcd/RPLD.dm @@ -247,23 +247,8 @@ if(duct_machine.duct_layer & layer_id) return FALSE -/obj/item/construction/plumbing/pre_attack_secondary(obj/machinery/target, mob/user, params) - if(!istype(target, /obj/machinery/duct)) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - var/obj/machinery/duct/duct = target - if(duct.duct_layer && duct.duct_color) - current_color = GLOB.pipe_color_name[duct.duct_color] - current_layer = GLOB.plumbing_layer_names["[duct.duct_layer]"] - balloon_alert(user, "using [current_color], layer [current_layer]") - - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - -/obj/item/construction/plumbing/afterattack(atom/target, mob/user, proximity) - . = ..() - if(!proximity) - return - +/obj/item/construction/plumbing/interact_with_atom(atom/target, mob/living/user, list/modifiers) + . = NONE for(var/category_name in plumbing_design_types) var/list/designs = plumbing_design_types[category_name] @@ -274,13 +259,26 @@ var/obj/machinery/machine_target = target if(machine_target.anchored) balloon_alert(user, "unanchor first!") - return + return ITEM_INTERACT_BLOCKING if(do_after(user, 2 SECONDS, target = target)) machine_target.deconstruct() //Let's not substract matter playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) //this is just such a great sound effect - return + return ITEM_INTERACT_SUCCESS + + if(create_machine(target, user)) + return ITEM_INTERACT_SUCCESS + +/obj/item/construction/plumbing/interact_with_atom_secondary(atom/target, mob/living/user, list/modifiers) + . = NONE + if(!istype(target, /obj/machinery/duct)) + return ITEM_INTERACT_BLOCKING - create_machine(target, user) + var/obj/machinery/duct/duct = target + if(duct.duct_layer && duct.duct_color) + current_color = GLOB.pipe_color_name[duct.duct_color] + current_layer = GLOB.plumbing_layer_names["[duct.duct_layer]"] + balloon_alert(user, "using [current_color], layer [current_layer]") + return ITEM_INTERACT_SUCCESS /obj/item/construction/plumbing/click_alt(mob/user) ui_interact(user) diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm index e3f9486bee9..2e8eaee9d6d 100644 --- a/code/modules/plumbing/plumbers/_plumb_machinery.dm +++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm @@ -11,6 +11,8 @@ processing_flags = START_PROCESSING_MANUALLY active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2.75 resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF + interaction_flags_machine = parent_type::interaction_flags_machine | INTERACT_MACHINE_OFFLINE + ///Plumbing machinery is always gonna need reagents, so we might aswell put it here var/buffer = 50 ///Flags for reagents, like INJECTABLE, TRANSPARENT bla bla everything thats in DEFINES/reagents.dm @@ -21,11 +23,42 @@ set_anchored(bolt) create_reagents(buffer, reagent_flags) AddComponent(/datum/component/simple_rotation) - interaction_flags_machine |= INTERACT_MACHINE_OFFLINE + register_context() + +/obj/machinery/plumbing/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(isnull(held_item)) + return + + if(held_item.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "[anchored ? "Un" : ""]Anchor" + return CONTEXTUAL_SCREENTIP_SET + else if(held_item.tool_behaviour == TOOL_WELDER && !anchored) + context[SCREENTIP_CONTEXT_LMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + else if(istype(held_item, /obj/item/plunger)) + context[SCREENTIP_CONTEXT_LMB] = "Flush" + return CONTEXTUAL_SCREENTIP_SET /obj/machinery/plumbing/examine(mob/user) . = ..() - . += span_notice("The maximum volume display reads: [reagents.maximum_volume] units.") + if(isobserver(user) || !in_range(src, user)) + return + + . += span_notice("The maximum volume display reads: [reagents.maximum_volume]u capacity. Contains:") + if(reagents.total_volume) + for(var/datum/reagent/reg as anything in reagents.reagent_list) + . += span_notice("[round(reg.volume, CHEMICAL_VOLUME_ROUNDING)]u of [reg.name]") + else + . += span_notice("Nothing.") + + if(anchored) + . += span_notice("It's [EXAMINE_HINT("anchored")] in place.") + else + . += span_warning("Needs to be [EXAMINE_HINT("anchored")] to start operations.") + . += span_notice("It can be [EXAMINE_HINT("welded")] apart.") + + . += span_notice("An [EXAMINE_HINT("plunger")] can be used to flush out reagents.") /obj/machinery/plumbing/wrench_act(mob/living/user, obj/item/tool) if(user.combat_mode) @@ -39,6 +72,23 @@ end_processing() return ITEM_INTERACT_SUCCESS +/obj/machinery/plumbing/welder_act(mob/living/user, obj/item/I) + if(user.combat_mode) + return NONE + + if(anchored) + balloon_alert(user, "unanchor first!") + return ITEM_INTERACT_BLOCKING + + if(I.tool_start_check(user, amount = 1)) + to_chat(user, span_notice("You start slicing the [name] apart.")) + if(I.use_tool(src, user, 1.5 SECONDS, volume = 50)) + deconstruct(TRUE) + to_chat(user, span_notice("You slice the [name] apart.")) + return ITEM_INTERACT_SUCCESS + + return ITEM_INTERACT_BLOCKING + /obj/machinery/plumbing/plunger_act(obj/item/plunger/P, mob/living/user, reinforced) user.balloon_alert_to_viewers("furiously plunging...") if(do_after(user, 3 SECONDS, target = src)) @@ -46,17 +96,6 @@ reagents.expose(get_turf(src), TOUCH) //splash on the floor reagents.clear_reagents() -/obj/machinery/plumbing/welder_act(mob/living/user, obj/item/I) - . = ..() - if(anchored) - to_chat(user, span_warning("The [name] needs to be unbolted to do that!")) - if(I.tool_start_check(user, amount=1)) - to_chat(user, span_notice("You start slicing the [name] apart.")) - if(I.use_tool(src, user, (1.5 SECONDS), volume=50)) - deconstruct(TRUE) - to_chat(user, span_notice("You slice the [name] apart.")) - return TRUE - ///We can empty beakers in here and everything /obj/machinery/plumbing/input name = "input gate" diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm index f75ec94f21c..bd0a69e6d5e 100644 --- a/code/modules/plumbing/plumbers/grinder_chemical.dm +++ b/code/modules/plumbing/plumbers/grinder_chemical.dm @@ -7,6 +7,9 @@ reagent_flags = TRANSPARENT | DRAINABLE buffer = 400 + /// Are we grinding or juicing + var/grinding = TRUE + /obj/machinery/plumbing/grinder_chemical/Initialize(mapload, bolt, layer) . = ..() AddComponent(/datum/component/plumbing/simple_supply, bolt, layer) @@ -15,17 +18,74 @@ ) AddElement(/datum/element/connect_loc, loc_connections) -/obj/machinery/plumbing/grinder_chemical/attackby(obj/item/weapon, mob/user, params) - if(istype(weapon, /obj/item/storage/bag)) - to_chat(user, span_notice("You dump items from [weapon] into the grinder.")) - for(var/obj/item/obj_item in weapon.contents) - grind(obj_item) - else - to_chat(user, span_notice("You attempt to grind [weapon].")) - grind(weapon) +/obj/machinery/plumbing/grinder_chemical/examine(mob/user) + . = ..() + + . += span_notice("Use empty hand to change operation mode. Currently [grinding ? "Grinding" : "Juicing"]") + +/** + * Check if the user can interact with the grinder + * Arguments + * + * * mob/user - the player we are checking for + */ +/obj/machinery/plumbing/grinder_chemical/proc/check_interactable(mob/user) + PRIVATE_PROC(TRUE) + return can_interact(user) + +/obj/machinery/plumbing/grinder_chemical/attack_hand(mob/living/user, list/modifiers) + if(user.combat_mode || !user.can_perform_action(src, ALLOW_SILICON_REACH | FORBID_TELEKINESIS_REACH)) + return FALSE + + var/list/options = list() + + var/static/radial_grind = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_grind") + options["grind"] = radial_grind + + var/static/radial_juice = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_juice") + options["juice"] = radial_juice + + var/choice = show_radial_menu( + user, + src, + options, + custom_check = CALLBACK(src, PROC_REF(check_interactable), user), + ) + if(!choice) + return FALSE + + grinding = (choice == "grind") return TRUE +/obj/machinery/plumbing/grinder_chemical/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = NONE + if(user.combat_mode || !user.can_perform_action(src, ALLOW_SILICON_REACH | FORBID_TELEKINESIS_REACH)) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(istype(tool, /obj/item/construction/plumbing)) + return tool.interact_with_atom(src, user, modifiers) + else if(istype(tool, /obj/item/plunger)) + return + else if(istype(tool, /obj/item/storage/bag)) + if(!anchored) + to_chat(user, span_warning("Anchor first to start [grinding ? "grind" : "juice"].")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You dump items from [tool] into the grinder.")) + for(var/obj/item/obj_item in tool.contents) + grind(obj_item) + return ITEM_INTERACT_SUCCESS + else if(!tool.tool_behaviour) + var/action = "[grinding ? "grind" : "juice"]" + if(!anchored) + to_chat(user, span_warning("Anchor first to star [action].")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You attempt to [action] [tool].")) + grind(tool) + return ITEM_INTERACT_SUCCESS + /obj/machinery/plumbing/grinder_chemical/CanAllowThrough(atom/movable/mover, border_dir) . = ..() if(!anchored) @@ -37,7 +97,7 @@ /obj/machinery/plumbing/grinder_chemical/proc/on_entered(datum/source, atom/movable/AM) SIGNAL_HANDLER - grind(AM) + INVOKE_ASYNC(src, PROC_REF(grind), AM) /** * Grinds/Juices the atom @@ -45,7 +105,9 @@ * * [AM][atom] - the atom to grind or juice */ /obj/machinery/plumbing/grinder_chemical/proc/grind(atom/AM) - if(!is_operational) + PRIVATE_PROC(TRUE) + + if(!is_operational || !anchored) return if(reagents.holder_full()) return @@ -53,11 +115,15 @@ return var/obj/item/I = AM + if((I.item_flags & ABSTRACT) || (I.flags_1 & HOLOGRAM_1)) + return + var/result - if(I.grind_results) - result = I.grind(reagents, usr) - else + if(!grinding) result = I.juice(reagents, usr) + else if(length(I.grind_results) || I.reagents?.total_volume) + result = I.grind(reagents, usr) + + use_energy(active_power_usage) if(result) - use_energy(active_power_usage) qdel(I) diff --git a/code/modules/plumbing/plumbers/vatgrower.dm b/code/modules/plumbing/plumbers/vatgrower.dm index 7327a648dad..1dcfb08e0cc 100644 --- a/code/modules/plumbing/plumbers/vatgrower.dm +++ b/code/modules/plumbing/plumbers/vatgrower.dm @@ -11,9 +11,9 @@ var/resampler_active = FALSE ///Add that sexy demnand component -/obj/machinery/plumbing/growing_vat/Initialize(mapload, bolt) +/obj/machinery/plumbing/growing_vat/Initialize(mapload, bolt, layer) . = ..() - AddComponent(/datum/component/plumbing/simple_demand, bolt) + AddComponent(/datum/component/plumbing/simple_demand, bolt, layer) /obj/machinery/plumbing/growing_vat/create_reagents(max_vol, flags) . = ..()