Files
3c5749f862 General maintenance for plumbing (#94427)
## About The Pull Request
The overall behaviour of everything should stay the same but the memory
& speed of these components has been slightly improved and when you
scale that across large plumbing factories you get a substantial
improvement. Here's a list of the most noticeable changes along with
many others that aren't worth mentioning

- Removed vars `use_overlays`, `turn_connects`,
`recipient_reagents_holder`
- `active` var is now replaced with a proc which simply returns is the
machine wrenched or not
- `turn_connects` has been removed because all machines have their pipes
rotate when the machine is rotated. This also removed all the static
icon states ending with `-s` from the `dmi` file thus reducing that file
size as well
- `extend_pipe_to_edge` var is directly integrated into `cut_overlays()`
because it's use cases were limited such for showers & sinks
- Simplified `Initialize()` a lot. Removed params `start`,
`turn_connects`, `custom_receiver`, `extend_pipe_to_edge`. We now only
pass `bolt_layer` making that proc faster & less convoluted
- Replaced `set_recipient_reagents_holder()` proc with
`recipient_reagents_holder()` which returns the reagent holder for
holding reagents instead of storing it in the component. This removes
the need to hook a qdel signal on the holder & we don't need to keep
track of it
- Merged a ton of procs to reduce overhead & reduce file size
- Plumbing ducts creating the network at mapload is faster without using
recursion and the timer subsystem
- Deconstructing plumbing ducts is faster in reconstructing the network
without using recursion and the timer subsystem

This makes managing plumbing code less convoluted & overall better for
the foreseeable future. See the lines of code removed vs added and still
preserves behaviour

## Changelog
🆑
qol: added examines & screentips for ducts & stack of ducts
qol: you can wrench a stack of ducts on the ground to create a pipe
refactor: plumbing code has been improved overall. Report bugs on github
sprite: removed unused static(does not rotate with machine) icon states
for plumbing connections
/🆑

---------

Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
2025-12-31 13:03:42 +01:00

124 lines
3.8 KiB
Plaintext

#define UNREADY 0
#define IDLE 1
#define READY 2
/obj/machinery/plumbing/buffer
name = "automatic buffer"
desc = "A chemical holding tank that waits for neighbouring automatic buffers to complete before allowing a withdrawal. Connect/reset by screwdrivering"
icon_state = "buffer"
pass_flags_self = PASSMACHINE | LETPASSTHROW // It looks short enough.
buffer = 200
///Buffer net that connects multiple buffers
var/datum/buffer_net/buffer_net
///Volume of reagents at which which this buffer is ready to send
var/activation_volume = 100
///The state of this machine see defines
var/mode
/obj/machinery/plumbing/buffer/Initialize(mapload, layer)
. = ..()
AddComponent(/datum/component/plumbing/buffer, layer)
/obj/machinery/plumbing/buffer/create_reagents(max_vol, flags)
. = ..()
RegisterSignal(reagents, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(on_reagent_change))
/obj/machinery/plumbing/buffer/proc/on_reagent_change()
SIGNAL_HANDLER
if(!buffer_net)
return
if(reagents.total_volume >= activation_volume && mode == UNREADY)
mode = IDLE
buffer_net.check_active()
else if(reagents.total_volume < activation_volume && mode != UNREADY)
mode = UNREADY
buffer_net.check_active()
/obj/machinery/plumbing/buffer/update_icon()
. = ..()
icon_state = initial(icon_state)
if(buffer_net)
switch(mode)
if(UNREADY)
icon_state += "_red"
if(IDLE)
icon_state += "_yellow"
if(READY)
icon_state += "_green"
/obj/machinery/plumbing/buffer/proc/attempt_connect()
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
for(var/atom/movable/movable in T)
if(istype(movable, /obj/machinery/plumbing/buffer))
var/obj/machinery/plumbing/buffer/neighbour = movable
if(neighbour.buffer_net != buffer_net)
neighbour.buffer_net?.destruct()
//we could put this on a proc, but its so simple I dont think its worth the overhead
buffer_net.buffer_list += neighbour
neighbour.buffer_net = buffer_net
neighbour.attempt_connect() //technically this would runtime if you made about 200~ buffers
add_overlay(icon_state + "_alert")
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/, cut_overlay), icon_state + "_alert"), 2 SECONDS)
/obj/machinery/plumbing/buffer/attack_hand_secondary(mob/user, modifiers)
. = ..()
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return
. = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
var/new_volume = tgui_input_number(user, "Enter new activation threshold", "Beepityboop", activation_volume, buffer)
if(!new_volume || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
activation_volume = new_volume
to_chat(user, span_notice("New activation threshold is now [activation_volume]."))
return
/obj/machinery/plumbing/buffer/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(item.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, span_notice("You reset the automatic buffer."))
//reset the net
buffer_net?.destruct()
buffer_net = new()
LAZYADD(buffer_net.buffer_list, src)
attempt_connect()
else
return . = ..()
/obj/machinery/plumbing/buffer/doMove(destination)
. = ..()
buffer_net?.destruct()
/datum/buffer_net
var/list/obj/machinery/plumbing/buffer/buffer_list
/datum/buffer_net/proc/destruct()
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
buffer.buffer_net = null
buffer_list.Cut()
qdel(src)
/datum/buffer_net/proc/check_active()
var/ready = TRUE
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
if(buffer.mode == UNREADY)
ready = FALSE
break
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
if(buffer.mode == READY && !ready)
buffer.mode = IDLE
else if(buffer.mode == IDLE && ready)
buffer.mode = READY
buffer.update_icon()
#undef UNREADY
#undef IDLE
#undef READY