From c779efbeec008d84d609b668fac423f6363e9ca5 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Wed, 4 Feb 2026 08:53:58 +0530 Subject: [PATCH] General maintenance for plumbing disposer (#94944) ## About The Pull Request - Plumbing disposer disposal rate can now be changed with hand nad has TGUI interface. It accepts a value between 5->15 meaning it can dispose anywhere from 10u to 50u reagents per tick. Added examines & screen tips for the same - Fixes plumbing disposer icon state not correctly switching between working and off under certain circumstances ## Changelog :cl: qol: plumbing disposer now has TGUI interface for operations fix: plumbing disposer icon state correctly switches between on & off under circumstances /:cl: --- .../components/plumbing/simple_components.dm | 13 +++ code/modules/plumbing/plumbers/destroyer.dm | 91 ++++++++++++++++--- .../packages/tgui/interfaces/ChemDisposer.tsx | 58 ++++++++++++ 3 files changed, 151 insertions(+), 11 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/ChemDisposer.tsx diff --git a/code/datums/components/plumbing/simple_components.dm b/code/datums/components/plumbing/simple_components.dm index c86dddda391..50ba2cc6a8a 100644 --- a/code/datums/components/plumbing/simple_components.dm +++ b/code/datums/components/plumbing/simple_components.dm @@ -20,6 +20,19 @@ edge_overlay.pixel_z = -parent_movable.pixel_y - parent_movable.pixel_z overlays += edge_overlay +///For disposing reagents +/datum/component/plumbing/simple_demand/disposer + +/datum/component/plumbing/simple_demand/disposer/Initialize(ducting_layer, distinct_reagent_cap) + if(!istype(parent, /obj/machinery/plumbing/disposer)) + return COMPONENT_INCOMPATIBLE + return ..() + +/datum/component/plumbing/simple_demand/disposer/send_request(dir) + var/obj/machinery/plumbing/disposer/target = parent + if(target.on) + process_request(target.disposal_rate * SSFLUIDS_DT, dir = dir) + ///has one pipe output that only supplies. example is liquid pump and manual input pipe /datum/component/plumbing/simple_supply supply_connects = SOUTH diff --git a/code/modules/plumbing/plumbers/destroyer.dm b/code/modules/plumbing/plumbers/destroyer.dm index db3100f10f8..b86d206f22f 100644 --- a/code/modules/plumbing/plumbers/destroyer.dm +++ b/code/modules/plumbing/plumbers/destroyer.dm @@ -1,25 +1,94 @@ +//Maximum disposal rate +#define MAX_DISPOSAL_RATE 25 + /obj/machinery/plumbing/disposer name = "chemical disposer" desc = "Breaks down chemicals and annihilates them." icon_state = "disposal" + base_icon_state = "disposal" pass_flags_self = PASSMACHINE | LETPASSTHROW // Small + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 4 - ///we remove 5 reagents per second + ///Reagents to remove per second var/disposal_rate = 5 + ///Is this machine switched on + var/on = FALSE /obj/machinery/plumbing/disposer/Initialize(mapload, layer) . = ..() - AddComponent(/datum/component/plumbing/simple_demand, layer) + AddComponent(/datum/component/plumbing/simple_demand/disposer, layer) + RegisterSignal(reagents, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(update)) + +/obj/machinery/plumbing/disposer/examine(mob/user) + . = ..() + . += span_notice("It is disposing [disposal_rate]u reagents per second.") + . += span_notice("Use hand to change disposal rate.") + +/obj/machinery/plumbing/disposer/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(isnull(held_item)) + context[SCREENTIP_CONTEXT_LMB] = "Set transfer rate" + return CONTEXTUAL_SCREENTIP_SET + + return ..() + +/obj/machinery/plumbing/disposer/proc/update() + SIGNAL_HANDLER + + update_appearance(UPDATE_ICON_STATE) + +/obj/machinery/plumbing/disposer/update_icon_state() + icon_state = "[base_icon_state][is_operational && anchored && on && reagents.total_volume ? "_working" : ""]" + return ..() + +/obj/machinery/plumbing/disposer/on_set_is_operational(old_value) + . = ..() + update_appearance(UPDATE_ICON_STATE) + +/obj/machinery/plumbing/disposer/wrench_act(mob/living/user, obj/item/tool) + . = ..() + if(. == ITEM_INTERACT_SUCCESS) + update_appearance(UPDATE_ICON_STATE) + +/obj/machinery/plumbing/disposer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemDisposer", name) + ui.open() + +/obj/machinery/plumbing/disposer/ui_static_data(mob/user) + return list( + max_volume = MAX_DISPOSAL_RATE + ) + +/obj/machinery/plumbing/disposer/ui_data(mob/user) + return list( + enabled = on, + disposal_rate = disposal_rate + ) + +/obj/machinery/plumbing/disposer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("toggle_power") + on = !on + update_appearance(UPDATE_ICON_STATE) + return TRUE + + if("change_volume") + var/num = text2num(params["volume"]) + if(!isnum(num)) + return FALSE + + disposal_rate = round(clamp(num, 0.1, MAX_DISPOSAL_RATE), CHEMICAL_VOLUME_ROUNDING) + return TRUE /obj/machinery/plumbing/disposer/process(seconds_per_tick) - if(!is_operational) + if(!is_operational || !reagents.total_volume || !on) return - if(reagents.total_volume) - if(icon_state != initial(icon_state) + "_working") //threw it here instead of update icon since it only has two states - icon_state = initial(icon_state) + "_working" - reagents.remove_all(disposal_rate * seconds_per_tick) - use_energy(active_power_usage * seconds_per_tick) - else - if(icon_state != initial(icon_state)) - icon_state = initial(icon_state) + reagents.remove_all(disposal_rate * seconds_per_tick) + use_energy((disposal_rate / MAX_DISPOSAL_RATE) * active_power_usage * seconds_per_tick) +#undef MAX_DISPOSAL_RATE diff --git a/tgui/packages/tgui/interfaces/ChemDisposer.tsx b/tgui/packages/tgui/interfaces/ChemDisposer.tsx new file mode 100644 index 00000000000..edfa711fdd7 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ChemDisposer.tsx @@ -0,0 +1,58 @@ +import { useBackend } from 'tgui/backend'; +import { + Button, + LabeledList, + NumberInput, + Section, +} from 'tgui-core/components'; +import type { BooleanLike } from 'tgui-core/react'; +import { Window } from '../layouts'; + +type Data = { + enabled: BooleanLike; + max_volume: number; + disposal_rate: number; +}; + +export function ChemDisposer() { + const { act, data } = useBackend(); + const { enabled, max_volume, disposal_rate } = data; + + return ( + + +
act('toggle_power')} + > + {enabled ? 'On' : 'Off'} + + } + > + + + + act('change_volume', { + volume: value, + }) + } + /> + + +
+
+
+ ); +}